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

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

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

Сообщение mirk » 18.05.2016 23:39:58

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


Но оптимально ли это?
Пишется ли это одним буфером или побайтно?
mirk
постоялец
 
Сообщения: 317
Зарегистрирован: 24.09.2007 10:03:39

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

Сообщение zub » 19.05.2016 00:01:35

Имхо лучше использовать вариант с хэндлами файлов, а не с файловыми переменными. Еще лучше наверно потоки.
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение mirk » 19.05.2016 00:17:37

zub писал(а):Имхо лучше использовать вариант с хэндлами файлов, а не с файловыми переменными.

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

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

TFileStream?
mirk
постоялец
 
Сообщения: 317
Зарегистрирован: 24.09.2007 10:03:39

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

Сообщение zub » 19.05.2016 00:33:12

>>Это что? Я думал 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?
да
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение Снег Север » 19.05.2016 09:30:35

Вообще-то первые два способа доступа к файлу - это, всего лишь, обертки над TFileStream. Так что принципиальной разницы я не вижу.
Как писать буфер, вроде бы, в любом случае определяет файловая система ОС.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

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;
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

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

Сообщение zub » 19.05.2016 12:57:46

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

Если выбирать из file и thandle - в последнем емнип набор функций побогаче
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение Дож » 19.05.2016 13:04:44

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

Это оптимально. Файл пишется всем блоком сразу, не побайтно.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

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

Сообщение shyub » 20.05.2016 07:47:20

Если необходимо писать большие объёмы данных, то целесообразно использовать поток:
Код: Выделить всё
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).
shyub
постоялец
 
Сообщения: 112
Зарегистрирован: 25.11.2014 23:15:19

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

Сообщение stanilar » 20.05.2016 23:08:26

mirk писал(а):Но оптимально ли это?

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

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

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

З.Ы. Думаю что выбор лучше остановить на том, что удобнее в конкретном случае.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

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

Сообщение zub » 20.05.2016 23:47:51

Во первых это не костыль, а во вторых винапи тут не причем
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

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

Сообщение SSerge » 21.05.2016 05:01:47

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


imho, не из соображений богатства функций стоит выбирать между этими двумя, а из тех соображений, что file - буферизованный интерфейс, хотите этого или нет, а handle - прямой интерфейс операционной системы, а дальше быстродействие зависит от того, поддерживает операционная система или нет буферизацию ввода/вывода для конкретного диска. Если вдруг ей позарез надо будет флушить операции записи после записи или чтения каждого байта - то получится катастрофическое падение производительности. В DOS это было очень наглядным.
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

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

Сообщение Mikhail » 21.05.2016 13:29:09

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


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


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

Никого не слушайте, дескрипторы тут не при чем. Если требуется тонкий контроль IO, то можно использовать THandleStream или FileRead(Write).
Mikhail
энтузиаст
 
Сообщения: 562
Зарегистрирован: 24.10.2013 16:06:47

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

Сообщение Sergei I. Gorelkin » 22.05.2016 03:46:21

Паскаль буферизует только текстовые файлы (тип textfile). Типизированные (file of foo) и нетипизированные (просто file) файлы не буферизуются и представляют собой такую же тоненькую обертку над системными вызовами, что и остальные упомянутые способы. Разница только в синтаксисе.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1395
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru