Как добавить данные в файл в win32
Я искал, чтобы сделать это, но я не могу найти, что я делаю неправильно. Я пытаюсь заставить эту функцию добавлять данные каждый раз, когда она вызывается, но она всегда делает это один раз. Если файл не существует, он создает новый и записывает в файл ТОЛЬКО один раз, если файл существует, он ничего не делает (или может перезаписать)
void WriteToFile (char data[],wchar_t filename[] )
{
HANDLE hFile;
DWORD dwBytesToWrite = (DWORD)strlen(data);
DWORD dwBytesWritten ;
BOOL bErrorFlag = FALSE;
hFile = CreateFile((LPCWSTR)filename, // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_NEW, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
DisplayError(TEXT("CreateFile"));
_tprintf(TEXT("Terminal failure: Unable to open file \"%s\" for write.\n"), filename);
return;
}
bErrorFlag = WriteFile(
hFile, // open file handle
data, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (FALSE == bErrorFlag)
{
DisplayError(TEXT("WriteFile"));
printf("Terminal failure: Unable to write to file.\n");
}
else
{
if (dwBytesWritten != dwBytesToWrite)
{
// This is an error because a synchronous write that results in
// success (WriteFile returns TRUE) should write all data as
// requested. This would not necessarily be the case for
// asynchronous writes.
printf("Error: dwBytesWritten != dwBytesToWrite\n");
}
else
{
_tprintf(TEXT("Wrote %d bytes to %s successfully.\n"), dwBytesWritten, filename);
}
}
CloseHandle(hFile);
}
И здесь я вызываю функцию в WM_COMMAND
//When a menu item selected execute this code
case IDM_FILE_SAVE:
saveBool = true;
char Str[] = "this is my own data";
wchar_t filename[] = L"data.txt";
WriteToFile(Str, filename);
break;
2 ответа
если файл существует, он ничего не делает
Так, как это должно быть. В соответствии с CreateFile()
документация:
СОЗДАТЬ НОВЫЙ
1
Создает новый файл, только если он еще не существует.Если указанный файл существует, функция завершается ошибкой, а код последней ошибки устанавливается в ERROR_FILE_EXISTS (80).
Если указанный файл не существует и является допустимым путем к месту для записи, создается новый файл.
Для того, что вы пытаетесь сделать, используйте OPEN_ALWAYS
вместо:
OPEN_ALWAYS
4
Открывает файл всегда.Если указанный файл существует, функция завершается успешно, а код последней ошибки устанавливается в ERROR_ALREADY_EXISTS (183).
Если указанный файл не существует и является допустимым путем к доступному для записи местоположению, функция создает файл, а код последней ошибки устанавливается равным нулю.
Вы можете использовать FILE_APPEND_DATA
спецификатор доступа, чтобы иметь CreateFile()
автоматический поиск в конце файла после его создания / открытия (в противном случае вам придется искать вручную, используя SetFilePointer/Ex()
), прежде чем записывать новые данные в файл.
Попробуй это:
void WriteToFile (char *data, wchar_t *filename)
{
HANDLE hFile;
DWORD dwBytesToWrite = strlen(data);
DWORD dwBytesWritten ;
BOOL bErrorFlag = FALSE;
hFile = CreateFileW(filename, // name of the write
FILE_APPEND_DATA, // open for appending
FILE_SHARE_READ, // share for reading only
NULL, // default security
OPEN_ALWAYS, // open existing file or create new file
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
DisplayError(TEXT("CreateFile"));
wprintf(L"Terminal failure: Unable to create/open file \"%s\" for writing.\n", filename);
return;
}
while (dwBytesToWrite > 0)
{
bErrorFlag = WriteFile(
hFile, // open file handle
data, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (!bErrorFlag)
{
DisplayError(TEXT("WriteFile"));
printf("Terminal failure: Unable to write to file.\n");
break;
}
wprintf(L"Wrote %u bytes to \"%s\" successfully.\n", dwBytesWritten, filename);
data += dwBytesWritten;
dwBytesToWrite -= dwBytesWritten;
}
CloseHandle(hFile);
}
В документации WriteFile говорится:
[вход, выход, необязательно] lpOverlapped
...
Чтобы записать в конец файла, укажите для членов Offset и OffsetHigh структуры OVERLAPPED значение 0xFFFFFFFF. Это функционально эквивалентно предыдущему вызову функции CreateFile для открытия hFile с использованием доступа FILE_APPEND_DATA.
Тогда вам не нужно использоватьFILE_APPEND_DATA
флаг илиSetFilePointer
илиSetFilePointerEx
функция для установки указателя в конец.
Это пример:
LPCWSTR fileName=L"D:\foo\bar.txt";
LPCWSTR buffer{0x20,0x33};
HANDLE fileHandle=CreateFileW(fileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
NULL,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
NULL);
OVERLAPPED writeFlag{0};
writeFlag.DUMMYUNIONNAME.DUMMYSTRUCTNAME.Offset=0xFFFFFFFF;
writeFlag.DUMMYUNIONNAME.DUMMYSTRUCTNAME.OffsetHigh=0xFFFFFFFF;
WriteFile(fileHandle,buffer,sizeof(buffer),&writeFlag);
Вы можете изменить буфер на любой буфер, который вам нужно записать в конце файла и имени файла.