Здесь просто неуместно вызывать GetLastError
. Вы смешиваете две разные модели обработки ошибок.
Вызовите GetLastError
сразу же после сбоя вызова API, если это указано в документации. Когда вы ее вызываете, какая-то другая функция вполне могла бы вызвать SetLastError
и сбросить значение.
Поэтому неправильно вызывать GetLastError
, поскольку вы не используете функции Win32, и вам следует удалить вызов GetLastError
. Ваш код должен быть:
procedure TForm1.Button1Click(Sender: TObject);
var
Stream: TStream;
begin
Stream := TFileStream.Create('d:\toto.docx', fmOpenRead);
try
// ....
finally
Stream.Free;
end;
end;
В случае ошибки будет возбуждено исключение, о котором сообщит обработчик исключений верхнего уровня.
Пакеты среды выполнения не должны влиять на то, как выполняется этот код.
Возможные причины ошибки: файл не существует или заблокирован.
Вы написали:
if Assigned(Stream) then
Stream.Free;
Это всегда бессмысленно, так как метод Free
также проверяет, является ли ссылка на объект nil
. Фактически ваш код эквивалентен:
if Assigned(Stream) then
if Assigned(Stream) then
Stream.Destroy;
Так что лучше положиться на тест внутри Free
и просто написать:
Stream.Free;
В комментариях вы заявляете, что действительно хотите проверить, заблокирован ли файл. Не используйте для этого файловый поток. Вместо этого сделайте следующее:
- Позвоните
CreateFile
, чтобы открыть файл.
- Проверьте возвращенный дескриптор на
INVALID_HANDLE_VALUE
, чтобы обнаружить ошибку.
- В случае ошибки используйте
GetLastError
, чтобы узнать причину ошибки.
- В противном случае закройте дескриптор с помощью
CloseHandle
.
Однако это не рекомендуется. Вы можете использовать этот подход, чтобы определить, что файл не заблокирован, но к тому времени, когда вы попытаетесь прочитать его, он будет заблокирован. Существует врожденное состояние гонки.
Как правило, лучше просить прощения, чем разрешения.
person
David Heffernan
schedule
08.04.2016