【问题标题】:Directory.GetFiles() gives weird return valuesDirectory.GetFiles() 给出奇怪的返回值
【发布时间】:2023-12-29 16:07:01
【问题描述】:

当我尝试使用名为 File Lock 的工具隐藏目录中的文件时,会出现此问题。这不是常规隐藏,因为我在 Windows 资源管理器中看不到它。 代码:

string[] textFiles = Directory.GetFiles(@"c:\mydir")
//0 files returned

string[] textFiles = Directory.GetFiles(@"c:\mydir", "*.txt")
//1 file returned: "c:\mydir\."
File.Exists(textFiles[0])
//false

第二个函数如何返回“c:\mydir\”。文件?我可以删除所有不存在的文件来解决我的问题,但我想知道为什么我得到一个“。”文件放在第一位。

【问题讨论】:

    标签: c# .net file io locking


    【解决方案1】:

    我没有使用 File Lock 工具的经验,但我可以假设它挂钩 FindFirstFile WinAPI 函数以保护某些文件不被列出(该函数由 .NET Directory.GetFiles() 函数使用)。而且这个钩子可以写一点... buggy :)

    您能否尝试禁用该工具并重新进行测试?
    您很可能会解决问题。
    但是如果你得到相同的结果,那就怪 Directory.GetFiles()。

    【讨论】:

    • 没有工具也能正常工作。当他开始锁定和隐藏文件时,我们的一位测试人员想到了检查一切是否正常;)
    • 可能将指向此主题的链接发送到 File Lock 工具支持可以让您的测试人员更快乐 :)
    【解决方案2】:

    更多调查:

    • C:\Test\是普通目录
    • C:\Test\text.txt 是一个普通的文本文件。
    • C:\Text\text2.txt 是文件锁隐藏的文本文件

    以下代码...

    using System;
    using System.IO;
    
    public static class GetFilesTest {
      public static void Main() {
        int counter = 0;
        DirectoryInfo dir = new DirectoryInfo(@"C:\Test");
        foreach (FileSystemInfo fsi in dir.GetFileSystemInfos("*.txt")) {
          Console.WriteLine("########### FileSystemInfo {0} ###########", ++counter);
          Console.WriteLine("fsi: {0}", fsi);
          Console.WriteLine("Exists: {0}", fsi.Exists);
          Console.WriteLine("FullName: {0}", fsi.FullName);
          Console.WriteLine("Name: {0}", fsi.Name);
          Console.WriteLine("Extension: {0}", fsi.Extension);
          Console.WriteLine("Attributes: {0}", fsi.Attributes);
        }
    
        counter = 0;
        string[] files = {@"C:\Test\test.txt", @"C:\Test\test2.txt"};
        foreach(string file in files) {
          FileSystemInfo fi = new FileInfo(file);
          Console.WriteLine("########### FileInfo {0} ###########", ++counter);
          Console.WriteLine("fi: {0}", fi);
          Console.WriteLine("Exists: {0}", fi.Exists);
          Console.WriteLine("FullName: {0}", fi.FullName);
          Console.WriteLine("Name: {0}", fi.Name);
          Console.WriteLine("Extension: {0}", fi.Extension);
          Console.WriteLine("Attributes: {0}", fi.Attributes);
          Console.WriteLine("Contents: {0}", File.ReadAllText(fi.FullName));
        }
      }
    }
    

    ...输出:

    ########### FileSystemInfo 1 ###########
    fsi: test.txt
    Exists: True
    FullName: C:\Test\test.txt
    Name: test.txt
    Extension: .txt
    Attributes: Archive
    ########### FileSystemInfo 2 ###########
    fsi: .
    Exists: False
    FullName: C:\Test\.
    Name: .
    Extension: .
    Attributes: Directory
    ########### FileInfo 1 ###########
    fi: C:\Test\test.txt
    Exists: True
    FullName: C:\Test\test.txt
    Name: test.txt
    Extension: .txt
    Attributes: Archive
    Contents: test
    ########### FileInfo 2 ###########
    fi: C:\Test\test2.txt
    Exists: True
    FullName: C:\Test\test2.txt
    Name: test2.txt
    Extension: .txt
    Attributes: Archive
    
    Unhandled Exception: System.UnauthorizedAccessException: Access to the path 'C:\Test\test2.txt' is denied.
       at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
       at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
       at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
       at System.IO.StreamReader..ctor(String path, Encoding encoding)
       at System.IO.File.ReadAllText(String path, Encoding encoding)
       at System.IO.File.ReadAllText(String path)
       at GetFilesTest.Main() in c:\Users\Yvonne\Temp\GetFilesTest.cs:line 29
    

    【讨论】:

    • 所以 GetFileSystemInfos("*.txt") 返回一个不存在的目录 "."。
    • 很明显,无论 File Lock 对文件做什么都会混淆 DirectoryInfo.GetFileSystemInfos 方法。在正常使用中它永远不会返回一个不存在的目录。
    • 是的,Rageous 可能是正确的,FileLock 工具挂钩到 .net 使用的 windows api。
    【解决方案3】:

    “。”指当前目录。试试:

    Directory.Exists(textFiles[0]);
    

    查看它的实际效果。

    为什么第二个重载返回他的条目而第一个没有,我不知道。

    【讨论】: