windows 在获取文件的大小或位置时是否应该引发异常?

ct2axkht  于 2022-12-05  发布在  Windows
关注(0)|答案(2)|浏览(115)

我试图在 Delphi 中创建一个处理文件的类。我有一个返回文件大小的属性和另一个返回文件位置的属性。我不知道这些调用是否会发生任何错误。我应该引发异常吗?
我的代码是:

function TFile.GetSize: Int64;
var
  FileSizeHi, FileSizeLo: Cardinal;
begin
  FileSizeLo := GetFileSize(FHandle, @FileSizeHi);
  if (FileSizeLo = INVALID_FILE_SIZE) and (GetLastError = NO_ERROR) then
    Result := $FFFFFFFF
  else
    Result := FileSizeLo or Int64(FileSizeHi) shl 32;
end;

function TFile.GetPosition: Int64;
var
  FilePosHi, FilePosLo: Cardinal;
begin
  FilePosHi := 0;
  FilePosLo := 0;
  FilePosLo := SetFilePointer(FHandle, FilePosLo, @FilePosHi, FILE_CURRENT);
  if (FilePosLo = INVALID_SET_FILE_POINTER) and (GetLastError = NO_ERROR) then
    Result := $FFFFFFFF
  else
    Result := FilePosLo or Int64(FilePosHi) shl 32;
end;

我不知道调用GetFileSize或SetFilePointer(不移动文件指针)时会发生什么错误。

wn9m85ua

wn9m85ua1#

这些都是WinAPI调用,您已经在检查返回值,所以您应该准备好了。检查函数返回值的工作由类的用户负责。有关更多信息,请查看SetFilePointer()GetFileSize()

zzlelutf

zzlelutf2#

是的,这些函数可能会发生错误,所以我建议引发一个异常,否则调用者不知道它是否收到了一个无效的值,因为$FFFFFFFF是64位值的有效大小/位置。也许你打算改用-1$FFFFFFFFFFFFFFFF)?
但是,不管你是否引发异常,你的GetLastError()检查都是错误的,它需要使用<>而不是=,当file函数对低值返回$FFFFFFFF时,GetLastError()会在低值真的是$FFFFFFFF而高值非零时返回0,否则,当低/高值无效时,GetLastError()将返回非零值。
试试这个:

function TFile.GetSize: Int64;
var
  FileSizeHi, FileSizeLo: DWORD;
begin
  FileSizeLo := GetFileSize(FHandle, @FileSizeHi);
  if (FileSizeLo = INVALID_FILE_SIZE) and (GetLastError <> NO_ERROR) then
    RaiseLastOSError // or: Result := -1
  else
    Result := FileSizeLo or (Int64(FileSizeHi) shl 32);
end;

function TFile.GetPosition: Int64;
var
  FilePosHi, FilePosLo: DWORD;
begin
  FilePosHi := 0;
  FilePosLo := 0;
  FilePosLo := SetFilePointer(FHandle, FilePosLo, @FilePosHi, FILE_CURRENT);
  if (FilePosLo = INVALID_SET_FILE_POINTER) and (GetLastError <> NO_ERROR) then
    RaiseLastOSError // or: Result := -1
  else
    Result := FilePosLo or (Int64(FilePosHi) shl 32);
end;

顺便说一句,考虑使用GetFileSizeEx()SetFilePointerEx(),因为它们对64位值进行操作,而不会将其分解为低/高部分。

相关问题