我用Delphi 7编写程序。我只需要使用它就可以处理非Unicode文件名。如果找到Unicode文件名,则应该忽略它。
我的代码如下:
var Filename: String;
if not FileExists(Filename) then Exit;
F := TFileStream(Filename, fmOpenRead or fmShareDenyWrite);
但是,对于某些Unicode文件名,FileExists()返回true,但随后TFileStream会引发异常,因为路径无效。
例如: 名为“ loop轮纹.jpg”的文件作为“ 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以获得正确的结果?
答案 0 :(得分:11)
不是TFileStream
本身,不是。但是,您可以改用Win32 CreateFileW()
打开Unicode文件名,然后将返回的HANDLE
分配给THandleStream
。这实际上就是TFileStream
内部所做的事情(在Delphi 7中使用CreateFileA()
代替)。
较新版本的Delphi在实现FileAge()
时使用Win32 GetFileAttributes()
1 而不是RTL的FileExists()
。 GetFileAttributes()
不像FindFirstFile()
那样支持通配符。
1。参见Why is GetFileAttributes the way old-timers test file existence?
或者,您根本无法在打开文件之前根本不检查文件是否存在,只是无条件打开它并捕获所产生的错误。操作系统会告诉您失败是由于找不到文件还是其他错误导致的。