2014-04-15 5 views
2

Я использую Delphi 2010 и ищу способ использовать функцию CreateFile Windows API для добавления данных, а не для их перезаписи в указанном файле?Как сообщить CreateFile, что я хочу добавить в существующий файл?

Я не ищу дополнительный способ сделать это, например Append() или Rewrite() или аналогичный. Я смотрю специально для этого, используя функцию CreateFile Windows API.

Я попытался с помощью:

// this will open existing file but will **overwrite** data in the file. 
fHandle:= CreateFile(PChar(FName), GENERIC_READ or GENERIC_WRITE, 0, 
     nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 

// this will recreate file each time therefore deleting its original content 
fHandle:= CreateFile(PChar(FName), GENERIC_READ or GENERIC_WRITE, 0, 
     nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 

Очень ценивший,

+2

Почему бы не ['TFileStream'] (http: /docwiki.embarcadero.com/VCL/2010/en/Classes.TFileStream)? Это простая в использовании оболочка этого API. Или используйте 'CreateFile' и [' THandleStream'] (http://docwiki.embarcadero.com/VCL/2010/ru/Classes.THandleStream) –

ответ

1

Указать, что вы хотите File_Append_Data доступ во втором параметре без также с просьбой о предоставлении File_Write_Data доступа. Тогда все записи будут в конце файла.

Чтобы открыть файл, создав его, если он еще не существует, выполните Open_Always для параметра dwCreationDisposition. (Для этого параметра документировано только пять возможных значений, поэтому вам не потребуется много времени, чтобы просмотреть список и выбрать тот, который наиболее точно соответствует вашим потребностям.)

+0

Привет, Роб и спасибо за ваш ответ. Я не уверен, что мне не хватает somethign, но я уже пытался использовать FILE_APPEND_DATA, и он говорит, что FILE_APPEND_DATA не объявлен. Я использую Delphi 2010. Вот что я делаю: fHandle: = CreateFile (PChar (FName), FILE_APPEND_DATA, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); –

+0

Вы можете заявить об этом сами. Его значение равно 4. –

+0

Спасибо. Это работает. –

2

Я подозреваю, что OPEN_ALWAYS на самом деле то, что вам нужно здесь.

Открывает файл, всегда. Если указанный файл существует, функция завершается успешно, а код последней ошибки установлен на ERROR_ALREADY_EXISTS (183).

Если указанный файл не существует и является допустимым путем к месту записи, функция создает файл, а код последней ошибки устанавливается на ноль.

И если вы пишите, то вы можете удалить GENERIC_READ.

Другая проблема, которую я ожидаю, заключается в том, что при открытии файла позиция файла устанавливается в начало файла. Ищите до конца, чтобы справиться с этим.

Win32Check(SetFilePointerEx(fHandle, 0, nil, FILE_END)); 

В качестве альтернативы вы можете использовать FILE_APPEND_DATA вместо GENERIC_WRITE.

Handle:= CreateFile(PChar(Name), FILE_APPEND_DATA, 0, 
    nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 

При использовании FILE_APPEND_DATA, при условии, что вы также не использовать FILE_WRITE_DATA, все записи сделаны в конце файла, независимо от текущего значения указателя файла.

documentation говорит так:

Для объекта файла, право добавлять данные в файл. (Для локальных файлов, операции записи не будет перезаписывать существующие данные, если этот флаг указан без FILE_WRITE_DATA.)

Обратите внимание, что более старые версии Delphi не определяют FILE_APPEND_DATA и поэтому вам нужно:

const 
    FILE_APPEND_DATA = $0004; 

Все это говорит о том, что я считаю, что лучший вариант здесь - это поток или класс писателя. Вы уверены, что хотите спуститься и заразиться Win32 API?

+3

Вы можете указать «FILE_APPEND_DATA» без 'FILE_WRITE_DATA' в параметре' dwDesiredAccess' из 'CreateFile()', и он будет автоматически записывать данные в конец файла без необходимости поиска в конце файла вручную. –

+0

@RemyLebeau Привет REmy и спасибо за ваш ответ. Я не уверен, что мне не хватает somethign, но я уже пытался использовать FILE_APPEND_DATA, и он говорит, что FILE_APPEND_DATA не объявлен. Я использую Delphi 2010. Вот что я делаю: fHandle: = CreateFile (PChar (FName), FILE_APPEND_DATA, 0, nil, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); –

+0

@ d.b: 'FILE_APPEND_DATA' был добавлен в блок' Windows' в XE. –