Использование WriteFile для заполнения кластера

Я хочу использовать Writefile для заполнения, а затем конца каждого файла, пока он не достигнет конца своего последнего кластера. Затем я хочу удалить то, что я написал, и повторить процесс (пытаясь избавиться от данных, которые могли быть там).

У меня есть 2 проблемы:

  1. WriteFile выдает ошибку: ERROR_INVALID_PARAMETER
  2. В зависимости от типа файла WriteFile() дает разные результаты

Итак, для первой проблемы я понял, что параметр nNumberOfBytesToWrite в WriteFile() должен быть кратным байтам на сектор (в моем случае 512 байт). Это ограничение функции или я что-то не так делаю?

Во втором выпуске я использую два фиктивных файла (.txt и .html) на внешнем жестком диске для записи случайных данных. В случае файла .txt данные записываются в конец файла, что мне и нужно. Однако файл .html просто записывается в начало файла и заменяет все данные, которые уже были там.

Вот несколько фрагментов кода, относящихся к моей проблеме:

hFile = CreateFile(result,          
                   GENERIC_READ | GENERIC_WRITE |FILE_READ_ATTRIBUTES,  
                   FILE_SHARE_READ | FILE_SHARE_WRITE,
                   0,                           
                   OPEN_EXISTING,                    
                   FILE_FLAG_NO_BUFFERING,
                   0);                          

if (hFile == INVALID_HANDLE_VALUE)  {
        cout << "File does not exist" << endl;
        CloseHandle(hFile);
}



DWORD dwBytesWritten;
char * wfileBuff = new char[512];
memset (wfileBuff,'0',512);

returnz = SetFilePointer(hFile, 0,NULL,FILE_END);
    if(returnz ==0){
        cout<<"Error: "<<GetLastError()<<endl;
};


LockFile(hFile, returnz, 0, 512, 0) 

returnz =WriteFile(hFile, wfileBuff, 512, &dwBytesWritten, NULL);
if(returnz ==0){
            cout<<"Error: "<<GetLastError()<<endl;
}

UnlockFile(hFile, returnz, 0, 512, 0);

cout<<dwBytesWritten<<endl<<endl;

В настоящее время я использую статические числа только для проверки функций.

Можно ли всегда писать в конец файла независимо от его типа? Я также пробовал SetFilePointer(hFile, 0,(fileSize - slackSpace + 1),FILE_BEGIN);, но это не сработало.


person DiegoU    schedule 20.06.2014    source источник


Ответы (1)


Вам необходимо ознакомиться с информацией в документации относительно FILE_FLAG_NO_BUFFERING . Конкретно этот раздел:

Как обсуждалось ранее, приложение должно соответствовать определенным требованиям при работе с файлами, открытыми с FILE_FLAG_NO_BUFFERING. Применяются следующие особенности:

  • Размеры доступа к файлу, включая необязательное смещение файла в структуре OVERLAPPED, если оно указано, должны быть для количества байтов, которое является целым числом, кратным размеру сектора тома. Например, если размер сектора составляет 512 байт, приложение может запрашивать чтение и запись 512, 1024, 1536 или 2048 байт, но не 335, 981 или 7171 байт.
  • Адреса буферов доступа к файлам для операций чтения и записи должны быть выровнены по физическому сектору, что означает, что они должны быть выровнены по адресам в памяти, кратным размеру физического сектора тома. В зависимости от диска это требование может не выполняться.
person David Heffernan    schedule 20.06.2014
comment
Вау, я полностью прошел через это. Спасибо! Любая идея о моей проблеме с типом файла? - person DiegoU; 20.06.2014
comment
Я не очень в это верю. Расширение файла не может влиять на работу WriteFile. - person David Heffernan; 20.06.2014
comment
Твое право! Теперь работает. Итак, чтобы удалить то, что я только что написал, я должен установить указатель на конец файла и написать пустые символы с помощью WriteFile или есть лучшая функция для использования? В идеале хотелось бы снова освободить место. - person DiegoU; 20.06.2014
comment
Я не особо слежу за всем этим. Если вы хотите написать, используйте WriteFile. Больше ничего нет. Снова освободить место? Освободить какое место? В любом случае, я думаю, что ответил на ваш вопрос. - person David Heffernan; 20.06.2014
comment
Я хочу удалить все символы, которые я только что написал с помощью WriteFile, чтобы освободить пространство, которое я только что использовал. - person DiegoU; 20.06.2014
comment
ОК, используйте SetFilePointerEx для исходного конечного местоположения файла, а затем вызовите SetEndOfFile. Кстати, не усложняйте жизнь, используя SetFilePointer. Используйте SetFilePointerEx. Подумайте о работе с файлами, размер которых не вписывается в 32-битное целое число. - person David Heffernan; 20.06.2014