-
var hFile : THandle; Tmp : LPDWORD; INRT : Int64;
hFile := CreateFile (PChar(FileName), FILE_ATTRIBUTE_READONLY, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if hFile = INVALID_HANDLE_VALUE then Exit; INRT := GetFileSize (hFile, @Tmp); StrError := PChar(SysErrorMessage(GetLastError)); StrError = 'Параметр задан неверно' Не подскажите в чем дело, что за параметр? От себя добавлю, что FileName является ВЗУ. Открываю я этот файл(ВЗУ) для редактирования filesystem. Конечно можно использовать цикл записи по n(512) байт, но это уморительно долго. И сразу второй вопрос. Произвожу запись файла ReadFile(FhDrive,GLArrayByte[0],SizeFile,br,nil) (с одной стороны здорово разом файл размером SizeFile байт) но возникает следущая задачка файл необходимо записывать в разные места диска (ВЗУ файловая система QNX4 - кто знает тот плавал) При записи файла размером 200м возникает не ловкая пауза перед пользователем. Опять же поблочная запись, по блокам(512) позволяет пользователю определить время на перекур по прогрессу, не подскажите как определить прогресс состояния записи в в случае быстрой(не поблочной) записи ReadFile(FhDrive,GLArrayByte[0],SizeFile,br,nil)
-
GetFileSize .. Parameters
hFile
Specifies an open handle of the file whose size is being returned. The handle must have been created with either GENERIC_READ or GENERIC_WRITE access to the file.
> не ловкая пауза перед пользователем
Изловчись выполнять подобного рода операции в дополнительном кодовом потоке, тогда будет "ловкая пауза"
-
> дополнительном кодовом потоке
что в этом потоке крутить? Я думал может есть какие ловушки, ну на крайний запустить процесс секунды на 3 глянуть сколько и за что.
> GENERIC_READ or GENERIC_WRITE
заменил не помогло.
-
> что в этом потоке крутить?
Крути все операции, за которые тебе стыдно перед юзером)
> думал может есть какие ловушки
Можно и без ловушек и без доп.потоков. На то существует overlapped-ввод/вывод, а также порты завершения
см. все что касается OVERLAPPED-режима Create/Read/WriteFile
-
OlegNik (25.12.08 12:12) но возникает следущая задачка файл необходимо записывать в разные места диска MMF не подойдет? мапить только то что нужно а не весь файл
-
OlegNik (25.12.08 12:12) но возникает следущая задачка файл необходимо записывать в разные места диска MMF не подойдет? мапить только то что нужно а не весь файл
-
пытался через OVERLAPPED но
hFile := CreateFile (PChar(FileName), FILE_ATTRIBUTE_READONLY, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
Да вроде можно посмотреть через WaitForSingleObjectEx сколько записал к определенной секунде, но увы не могу понять почему перестал работать SetFilePointer или аналог _llSeek, может знает кто?
-
> перестал работать > SetFilePointer
Неужели вот прямо так и говорит "Я перестал работать" ?
-
> Неужели вот прямо так и говорит "Я перестал работать" ?
Да нет, не прямо так. Говорит 'Параметр задан неверно'. Функция возвращает High(DWord); SetFilePointer(hFile, tmpLo , @tmpHi, FILE_BEGIN);
-
> OlegNik (26.12.08 16:58) [6]
> увы не могу понять почему перестал работать > SetFilePointer или аналог _llSeek, может знает кто?
The file pointer identified by the value of the hFile parameter is not used for overlapped read and write operations. To specify the offset for overlapped operations, use the Offset and OffsetHigh members of the OVERLAPPED structure.
-- Regards, LVT.
-
> To specify the offset for overlapped > operations, use the Offset and OffsetHigh members > of the OVERLAPPED structure.
А не в курсе как заполнять OVERLAPPED?
-
> OlegNik (27.12.08 12:39) [10]
> А не в курсе как заполнять OVERLAPPED?
Ну, каждое поле и заполнять. А чего, msdn.microsoft.com не работает?
-- Regards, LVT.
-
Виноват не то спросил.
FillChar(Overlap,SizeOf(TOVERLAPPED),0); Overlap.hEvent := CreateEvent(0,True,False,0); Overlap.offSet := 512 * 9000; res := WriteFileEx();
while WaitForSingleObjectEx(Overlap.hEvent,1000,True) = WAIT_TIMEOUT do begin Application.ProcessMessages; end;
В части записи с нужной мне позиции все нормально запись прозводится в поном объеме, но по истечению времени t=1с, я не вижу фактического изменения числа записанных байт в Overlap, что не так. Или возможно путь указаный т. Сергей М. ложный.
-
см. GetOverlappedResult
-
> см. GetOverlappedResult
while WaitForSingleObjectEx(Overlap.hEvent,1000,True) = WAIT_TIMEOUT do begin GetOverlappedResult(hFile,Overlap,realW,False); Form1.Caption := IntToStr(realW); {при GetOverlappedResult(hFile,Overlap,realW,True); уходит ПО в "себя"} Application.ProcessMessages; end;
-
ну и понятно realW = 0.
-
while True do begin case WaitForSingleObjectEx(Overlap.hEvent,1000,True) of WAIT_TIMEOUT: //прошла секунда, но сигнал окончания ovl-операции не обнаружен begin Application.ProcessMessages; continue; //ждем дальше end; WAIT_OBJECT_0: // обнаружен сигнал завершения ovl-операции begin Win32Check(GetOverlappedResult(hFile,Overlap,realW,False) <> 0); Form1.Caption := IntToStr(realW); break; end; end; end;
-
Это понятно и здорово. Но мне хотелось бы узнать сколько байт записано по истечению секунды на WAIT_TIMEOUT: Win32Check(GetOverlappedResult(hFile,Overlap,realW,False) <> False); выдает ошибку "наложенное событие ввода/вывода не находится в сигнальном состоянии" короче code : 996. Как быть?
-
Никак.
WAIT_TIMEOUT означает, что по истечении указанного периода операция не завершилась. Запрашивать результаты незавершенной операции бессмысленно, о чем собссно и говорит отказ с кодом 996.
-
Ну а теперь самое главное. Я против того, чтобы делать ради того чтобы делать. Мой вопрос заключался в следующем: Можно ли при записи данных большого объема что называется "за раз" узнать сколько байт записано к определенному моменту времени, хотябы для вывода вывода этих данных в прогресс. А что был за совет с
> см. все что касается OVERLAPPED-режима Create/Read/WriteFile
Блеск знаниями или что? Но всеравно спасибо за "науку".
|