如何快速验证区分大小写的文件名是否真实存在?

3

我需要制作一个与Unix兼容的Windows Delphi例程,以确认文件名在文件系统中是否与所需的大小写完全相同,例如“John.txt”存在,而不是“john.txt”。

如果我检查“FileExists('john.txt')”,它对于John.txt和JOHN.TXT始终为真,这是由于Windows。

如何创建“FileExistsCaseSensitive(myfile)”函数来确认文件确实是它应该是的。

DELPHI Sysutils.FileExists使用以下函数来查看文件是否存在,如何更改它以双重检查文件名在文件系统中是小写并存在:

function FileAge(const FileName: string): Integer;
var
  Handle: THandle;
  FindData: TWin32FindData;
  LocalFileTime: TFileTime;
begin
  Handle := FindFirstFile(PChar(FileName), FindData);
  if Handle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(Handle);
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    begin
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi,
        LongRec(Result).Lo) then Exit;
    end;
  end;
  Result := -1;
end;
5个回答

7
function FileExistsEx(const FileName: string): Integer;
var
  Handle: THandle;
  FindData: TWin32FindData;
  LocalFileTime: TFileTime;
begin
  Handle := FindFirstFile(PChar(FileName), FindData);
  if Handle <> INVALID_HANDLE_VALUE then
  begin
    Windows.FindClose(Handle);
    if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
    begin
      FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
      if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi, LongRec(Result).Lo) then
        if AnsiSameStr(FindData.cFileName, ExtractFileName(FileName)) then Exit;
    end;
  end;
  Result := -1;
end;

Tom,我对你的使用案例也很感兴趣。我倾向于赞同Motti的观点,这可能会适得其反,并让你的用户感到奇怪。


FileExistsEx返回一个整数?嗯,问题中的示例使用了FileAge。 - Toon Krijthe
@Gamecat - 我知道。我使用并更改了FileAge实现,并尝试重构它以返回布尔值。很快就变得混乱了。FileTimeToDosDateTime使用Result并期望它是一个整数。我知道,声明一个本地变量来传递等等...把这留给读者作为练习。 - Lieven Keersmaekers
1
只是一个小细节,但是给定文件 "C:\Folder\File.txt";FileExistsEx("c:\fOlDeR\File.txt") 将返回 true,这可能不是你想要的... - Roddy

4
在Windows操作系统中,文件名不区分大小写,因此我不认为在处理文件名时区分大小写有什么好处。无论如何,您不能同时拥有两个名为“John.txt”和“john.txt”的文件,如果只存在“john.txt”而无法找到“John.txt”,可能会导致用户非常困惑。在这种情况下强制区分大小写是不直观的,我无法看到其可行用例(如果您有一个,我很乐意听听它是什么)。

我有一个问题。我正在使用一个宏,该宏从文件夹浏览器对话框中打开目录。当给定的路径在大小写上完全相等时,该宏才能正常工作。然而,我的计算机有一个名为“Binary”的目录,而我的朋友的计算机则是“binary”。由于种种原因,我既不能更改宏也不能更改目录。因此,在使用路径之前,我需要验证路径是否大小写相等 ;) https://dev59.com/AmQo5IYBdhLWcg3wR9rD - theknut

1

我曾经处理过这个问题,虽然我确信有更好的解决方案,但最终我只是做了一个额外的检查,看看给定的文件名是否等于找到的文件名,使用区分大小写的字符串比较器...


很抱歉,这不是Delphi,但在Java中它看起来像这样: if (file.getName().equals(fileName)) doStuff(); - Mia Clarke

1

我在使用Java时遇到了类似的问题。最终,我列出了目录内容的列表(每个文件的文件名都正确地加载了大小写),然后对每个文件的文件名进行字符串比较。

这是一个丑陋的hack,但它起作用了。

编辑:我尝试了Banang所描述的方法,但至少在Java中,如果您打开文件“a.txt”,即使底层文件系统将其命名为“A.txt”,您的程序也会顽固地报告它为“a.txt”。


看起来我们在同一艘船上,Kris... :) - Mia Clarke

0

您可以使用Delphi的FindFirst和FindNext例程来实现Kris提到的方法。

请参见本文


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接