我在Delphi 7中编写程序。我只需要它来处理非Unicode文件名。如果找到Unicode文件名,它应该忽略它。
我的代码看起来像这样:
var Filename: String;
if not FileExists(Filename) then Exit;
F := TFileStream(Filename, fmOpenRead or fmShareDenyWrite);
但是,在某些Unicode文件名的情况下,FileExists()返回true,但TFileStream会引发异常,因为路径无效。
例如:一个名为“loop wheeltoo .jpg”的文件被读入Filename作为“loop ?? .jpg”。这是预期的行为。 TFileStream无法读取此类文件(因为目录中没有“loop ??。jpg”)并引发异常。但FileExists()应该捕获该文件不存在。为什么它不起作用?因为它被定义为:
function FileExists(const FileName: string): Boolean;
begin
Result := FileAge(FileName) <> -1;
end;
和FileAge()定义为:
function FileAge(const FileName: string): Integer;
var
Handle: THandle;
FindData: TWin32FindData;
LocalFileTime: TFileTime;
begin
Handle := FindFirstFile(PChar(FileName), FindData);
...
FindFirstFile使用“loop ??。jpg”作为掩码,然后找到“loop轮纹.jpg”。
所以问题是:
1)我可以在Delphi 7中以某种方式在TFileStream中轻松使用Unicode文件名吗?
要么
2)我应该使用什么功能而不是FileExists来获得正确的结果?
TFileStream
本身,没有。但您可以使用Win32 CreateFileW()
打开Unicode文件名,然后将返回的HANDLE
分配给THandleStream
。这基本上是TFileStream
内部所做的(在Delphi 7中使用CreateFileA()
)。GetFileAttributes()
1而不是RTL的FileAge()
来实现FileExists()
。 GetFileAttributes()
不支持通配符,就像FindFirstFile()
那样。
1.见Why is GetFileAttributes the way old-timers test file existence?或者,您可以在打开文件之前根本不检查文件是否存在,只需无条件打开它并捕获产生的错误。操作系统会告诉您失败是由于找不到文件而导致的其他错误。