Страница 1 из 1

Как правильно работать с файлами

СообщениеДобавлено: 18.05.2016 23:39:58
mirk
Пишу в файл довольно просто:
Код: Выделить всё
assign(f, '.....');
rewrite(f, 1);
blockwrite(fd, buf^, size);


Но оптимально ли это?
Пишется ли это одним буфером или побайтно?

Re: Как правильно работать с файлами

СообщениеДобавлено: 19.05.2016 00:01:35
zub
Имхо лучше использовать вариант с хэндлами файлов, а не с файловыми переменными. Еще лучше наверно потоки.

Re: Как правильно работать с файлами

СообщениеДобавлено: 19.05.2016 00:17:37
mirk
zub писал(а):Имхо лучше использовать вариант с хэндлами файлов, а не с файловыми переменными.

Это что? Я думал fd в моем случае и есть хэндл.

zub писал(а):Еще лучше наверно потоки.

TFileStream?

Re: Как правильно работать с файлами

СообщениеДобавлено: 19.05.2016 00:33:12
zub
>>Это что? Я думал fd в моем случае и есть хэндл.
в вашем случае
Код: Выделить всё
...
var
fd:file;
...

Приводите полный код пжст, телепаторы ломаются часто))
я говорю о
Код: Выделить всё
program Project1;
uses sysutils;
var
   fh:THandle;
   something:integer;
begin
   fh:=FileCreate('test.test');
   FileWrite(fh, something, sizeof(something));
   FileClose(fh);
end.


>>TFileStream?
да

Re: Как правильно работать с файлами

СообщениеДобавлено: 19.05.2016 09:30:35
Снег Север
Вообще-то первые два способа доступа к файлу - это, всего лишь, обертки над TFileStream. Так что принципиальной разницы я не вижу.
Как писать буфер, вроде бы, в любом случае определяет файловая система ОС.

Re: Как правильно работать с файлами

СообщениеДобавлено: 19.05.2016 12:53:42
Дож
Снег Север писал(а):Вообще-то первые два способа доступа к файлу - это, всего лишь, обертки над TFileStream.

Нет, сам TFileStream — обёртка над хендлами:

rtl/objpas/classes/streams.inc
Код: Выделить всё
function THandleStream.Write(const Buffer; Count: Longint): Longint;

begin
  Result:=FileWrite (FHandle,Buffer,Count);
  If Result=-1 then Result:=0;
end;

....

constructor TFileStream.Create(const AFileName: string; Mode: Word; Rights: Cardinal);

begin
  FFileName:=AFileName;
  If (Mode and fmCreate) > 0 then
    FHandle:=FileCreate(AFileName,Mode,Rights)
  else
    FHAndle:=FileOpen(AFileName,Mode);

  If (THandle(FHandle)=feInvalidHandle) then
    If Mode=fmcreate then
      raise EFCreateError.createfmt(SFCreateError,[AFileName])
    else
      raise EFOpenError.Createfmt(SFOpenError,[AFilename]);
end;

Re: Как правильно работать с файлами

СообщениеДобавлено: 19.05.2016 12:57:46
zub
>>Вообще-то первые два способа доступа к файлу - это, всего лишь, обертки над TFileStream.
Тогда уж TFileStream обертка над "хэндловыми" файлами, но не наоборот.

Если выбирать из file и thandle - в последнем емнип набор функций побогаче

Re: Как правильно работать с файлами

СообщениеДобавлено: 19.05.2016 13:04:44
Дож
mirk писал(а):Но оптимально ли это?
Пишется ли это одним буфером или побайтно?

Это оптимально. Файл пишется всем блоком сразу, не побайтно.

Re: Как правильно работать с файлами

СообщениеДобавлено: 20.05.2016 07:47:20
shyub
Если необходимо писать большие объёмы данных, то целесообразно использовать поток:
Код: Выделить всё
var
  Stream: TFileStream;
  BufStr: TWriteBufStream;
  M: array{1..300] of byte;
  ...
begin
  .........
  if SaveDialog1.Execute then begin
    try
      Stream:=TFileStream.Create(SaveDialog1.FileName, fmCreate or fmOpenWrite);
      BufStr:=TWriteBufStream.Create(Stream);
      BufStr.Write(M, 300);
      Result:=false;
      finally
        BufStr.Free;
        Stream.Free;
      end;
   end;
end;

Размер записываемого массива указан 300 байт для примера. Реально при таком размере преимуществ потока не увидите.

Добавлено спустя 6 минут 40 секунд:
Кажется я не правильно объявил массив. Надо было от 0 до 299 (не уверен, но у себя объявляю от 0).

Re: Как правильно работать с файлами

СообщениеДобавлено: 20.05.2016 23:08:26
stanilar
mirk писал(а):Но оптимально ли это?

Это костыль для поддержки кода из далеких девяностых. И, извините за любопытство, зачем Вам знать о том, насколько это оптимально?

zub писал(а):Если выбирать из file и thandle - в последнем набор функций побогаче

В последнем случае имеется весь набор Windows API, не знаю как в линухе.

З.Ы. Думаю что выбор лучше остановить на том, что удобнее в конкретном случае.

Re: Как правильно работать с файлами

СообщениеДобавлено: 20.05.2016 23:47:51
zub
Во первых это не костыль, а во вторых винапи тут не причем

Re: Как правильно работать с файлами

СообщениеДобавлено: 21.05.2016 05:01:47
SSerge
zub писал(а):Если выбирать из file и thandle - в последнем емнип набор функций побогаче


imho, не из соображений богатства функций стоит выбирать между этими двумя, а из тех соображений, что file - буферизованный интерфейс, хотите этого или нет, а handle - прямой интерфейс операционной системы, а дальше быстродействие зависит от того, поддерживает операционная система или нет буферизацию ввода/вывода для конкретного диска. Если вдруг ей позарез надо будет флушить операции записи после записи или чтения каждого байта - то получится катастрофическое падение производительности. В DOS это было очень наглядным.

Re: Как правильно работать с файлами

СообщениеДобавлено: 21.05.2016 13:29:09
Mikhail
mirk писал(а):Пишу в файл довольно просто:
Код: Выделить всё
assign(f, '.....');
rewrite(f, 1);
blockwrite(fd, buf^, size);


Но оптимально ли это?
Пишется ли это одним буфером или побайтно?


В Windows и Linux будет буферизоваться ОС. Но это, все равно, не очень хорошо, т.к. буфер будет "на стороне ядра" и доступ к нему потребует переключения контекста. Лучше сделать буфер на стороне приложения, если данных много.

Никого не слушайте, дескрипторы тут не при чем. Если требуется тонкий контроль IO, то можно использовать THandleStream или FileRead(Write).

Re: Как правильно работать с файлами

СообщениеДобавлено: 22.05.2016 03:46:21
Sergei I. Gorelkin
Паскаль буферизует только текстовые файлы (тип textfile). Типизированные (file of foo) и нетипизированные (просто file) файлы не буферизуются и представляют собой такую же тоненькую обертку над системными вызовами, что и остальные упомянутые способы. Разница только в синтаксисе.