Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как записать данные в начало файла [D7, XP]


Setor ©   (2006-03-27 19:04:00) 

Требуется записать данные в начало файла (headers). Размер файла более 100Мб. Пока что приходится создавать новый файл, записывать в него Header, а сверху добавлять содержимое огромного файла. Это медленно и нерационально. Попытался сделать Seek Отрицательным, но в документации сказано, что "Seek moves to the position Offset. Offset must be >= 0". Не работает, начало файла заменяется новыми данными, а мне нужно лишь его дополнить.

Логически это верно - файл создаётся на диске и может быть дополнен с конца или полностью перезаписан. Может есть какой-то оптимальный алгоритм, или всётаки придётся копировать сотни мегабайт из 1 файла в другой?

var
 MyStream: TFileStream;
begin
 MyStream:= TFileStream.Create( 'test.txt', fmOpenReadWrite );
 try
   MyStream.Seek( -4, soFromBeginning );
   MyStream.Write( 'test', 4 );
 finally
   MyStream.Free;
 end;


Leonid Troyanovsky   (2006-03-29 14:09:00) [1]


> MBo ©   (29.03.06 13:29) [5]


IMHO, не стоит делать просмотр на 100Мб, лучше уж по-старинке,
переносить буфером размером с кластер.

--
Regards, LVT.


MBo   (2006-03-29 13:29:00) [2]


function AddStartData(const FileName: string; var Data; Size: Integer): Boolean;
var
 hf, hm: THandle;
 i, OldSize: Integer;
 pb: PByteArray;
begin
 Result := False;
 hf := FileOpen(FileName, fmOpenReadWrite);
 if hf <> INVALID_HANDLE_VALUE then begin
   OldSize := GetFileSize(hf, nil);
   SetFilePointer(hf, OldSize + Size, nil, FILE_BEGIN);
   SetEndOfFile(hf);
   hm := CreateFileMapping(hf, nil, PAGE_READWRITE, 0, 0, nil);
   if hm > 0 then begin
     pb := MapViewOfFile(hm, FILE_MAP_ALL_ACCESS, 0, 0, 0);
     if pb <> nil then begin
       for i := OldSize - 1 downto 0 do
         pb[i + Size] := pb[i];
       Move(Data, pb[0], Size);
       FlushViewOfFile(pb, 0);
       UnMapViewOfFile(pb);
       Result := True;
     end;
     CloseHandle(hm);
   end;
   CloseHandle(hf);
 end;
end;


Пример использования:

s := StringOfChar('A', 100) + #13#10;
AddStartData('e:\data.dat', s[1], Length(s));


Alarm   (2006-03-29 08:53:00) [3]

Запиши свой заголовок в файл и "склей" его со 100мгб файлом

copy /b file1 + file2 newfile


Германн   (2006-03-29 02:06:00) [4]


> Гаврила ©   (28.03.06 21:55) [2]
>
> а если в рамках одного файла?
> все сдвинуть назад на размер хедера, и вписать что надо


А это, пардон, как?


Гаврила   (2006-03-28 21:55:00) [5]

а если в рамках одного файла?
все сдвинуть назад на размер хедера, и вписать что надо


Джо   (2006-03-27 19:06:00) [6]

> или всётаки придётся копировать сотни мегабайт из 1 файла
> в другой?

Придется :)


Наверх

Титульная страница Поиск, карта сайта Написать письмо