代码之家  ›  专栏  ›  技术社区  ›  flipdoubt

当Directory.GetFiles()发现不“喜欢”的文件名时抛出异常时,如何处理异常?

  •  3
  • flipdoubt  · 技术社区  · 17 年前

    System.ArgumentException message: Illegal characters in path.
    Argument: ""
    Stack trace:
       at System.IO.Path.CheckInvalidPathChars(String path)
       at System.IO.Path.InternalCombine(String path1, String path2)
       at System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption)
       at System.IO.Directory.GetFiles(String path, String searchPattern, SearchOption searchOption)
       at System.IO.Directory.GetFiles(String path)
       at Microsoft.Samples.XFileExplorer.ContentView.CreateContentDataTable(String CurrentFolder) in C:\Users\david\Downloads\MEF Preview 5\MEF Preview 5\Samples\XFileExplorer\XFileExplorer\ContentView.xaml.cs:line 108
    

    Vista计算机恰好被运行MacFuse的Mac访问,因此该目录包含一个名为“.\u Icon”的文件,但肯定包含一些非法字符。我相信这是错误的根源。当Directory.GetFiles()遇到一个它不喜欢的文件名时抛出异常时,我要做什么?是否有其他方法列出不通过此类异常的文件内容?

    对于此特定文件,我怀疑文件名必须包含Windows资源管理器或命令提示符未显示的某些字符:

       C:\Users\david>dir ._Icon
       Volume in drive C is Bootcamp
       Volume Serial Number is XXXX-XXX
    
       Directory of C:\Users\david
    
       File Not Found
    

       C:\Users\david>dir ._Icon*
       Volume in drive C is Bootcamp
       Volume Serial Number is XXXX-XXX
       Directory of C:\Users\david
    
       05/25/2008  07:40 AM            43,296 ._Icon
               1 File(s)         43,296 bytes
               0 Dir(s)  58,950,623,232 bytes free
    

    在SMB中查看该文件时,该文件似乎实际命名为“\u Icon?”。每次我试图从Mac上删除该文件时,该文件似乎会立即重新出现。

    4 回复  |  直到 17 年前
        1
  •  1
  •   Preet Sangha    17 年前

    你能试着用PInvoke列出这个文件吗 查找第一个文件 see here . is是否会导致Simmiller问题?

    文件信息将在中返回 WIN32 FIND DATA 结构。然后你打电话 FindNextFile 直到每个文件不返回0为止。在结构中,可以使用cFileName成员获取文件名。检查一下里面有什么是无效的。

    以下是其使用示例:

    public const int MAX_PATH = 260;
     public const int MAX_ALTERNATE = 14;
    
    [StructLayout(LayoutKind.Sequential)]
        public struct FILETIME {
        public uint dwLowDateTime;
        public uint dwHighDateTime;
     }; 
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] 
    public struct WIN32_FIND_DATA {
        public FileAttributes dwFileAttributes;
        public FILETIME ftCreationTime; 
        public FILETIME ftLastAccessTime; 
        public FILETIME ftLastWriteTime; 
        public int nFileSizeHigh;
        public int nFileSizeLow;
        public int dwReserved0;
        public int dwReserved1;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_PATH)] 
        public string cFileName; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAX_ALTERNATE)] 
        public string cAlternate; 
    }
    
    [DllImport("kernel32", CharSet=CharSet.Unicode)] 
    public static extern IntPtr FindFirstFile(string lpFileName, out WIN32_FIND_DATA lpFindFileData);
    
    [DllImport("kernel32", CharSet=CharSet.Unicode)] 
    public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData);
    
    private long RecurseDirectory(string directory, int level, out int files, out int folders) {
        IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
        long size = 0;
        files = 0;
        folders = 0;
        Kernel32.WIN32_FIND_DATA findData;
    
        IntPtr findHandle;
    
        // please note that the following line won't work if you try this on a network folder, like \\Machine\C$
        // simply remove the \\?\ part in this case or use \\?\UNC\ prefix
        findHandle = Kernel32.FindFirstFile(@"\\?\" + directory + @"\*", out findData);
        if (findHandle != INVALID_HANDLE_VALUE) {
    
            do {
                if ((findData.dwFileAttributes & FileAttributes.Directory) != 0) {
    
                    if (findData.cFileName != "." && findData.cFileName != "..") {
                        folders++;
    
                        int subfiles, subfolders;
                        string subdirectory = directory + (directory.EndsWith(@"\") ? "" : @"\") + 
                            findData.cFileName;
                        if (level != 0)  // allows -1 to do complete search.
                            {
                        size += RecurseDirectory(subdirectory, level - 1, out subfiles, out subfolders);
    
                        folders += subfolders;
                        files += subfiles;
                        }
                    }
                }
                else {
                    // File
                    files++;
    
                    size += (long)findData.nFileSizeLow + (long)findData.nFileSizeHigh * 4294967296;
                }
            } 
            while (Kernel32.FindNextFile(findHandle, out findData));
            Kernel32.FindClose(findHandle);
    
        }
    
        return size;
    }
    
    // [Sample by KÃ¥re Smith] // [Minor edits by Mike Liddell]
    
        2
  •  1
  •   mpjda    16 年前

    http://en.wikipedia.org/wiki/Resource_fork

    从Microsoft sysinternals站点:

    NTFS文件系统为应用程序提供了创建备用信息数据流的能力。默认情况下,所有数据都存储在文件的主未命名数据流中,但通过使用“file:stream”语法,您可以读取和写入备用数据。并非所有应用程序都是为了访问备用流而编写的,但您可以非常简单地演示流。首先,在命令提示符下更改为NTFS驱动器上的目录。接下来,键入“echo hello>测试:流'。您刚刚创建了一个名为“stream”的流,它与文件“test”关联。请注意,当您查看测试的大小时,它报告为0,并且在任何文本编辑器中打开时,该文件看起来是空的。要查看您的流,请输入“更多<test:stream'(type命令不接受流语法,因此您必须使用更多)。

        3
  •  0
  •   John Saunders    17 年前

    直接删除或重命名文件怎么样?

        4
  •  0
  •   Malcomm    15 年前

    我知道这有点过时,但我刚刚遇到了从Windows访问OSX文件系统的完全相同的问题。 DotNet给了我“非法文件名”错误,原因是一个名为icon的零字节Mac文件,但文件名末尾有一个正方形。

    FSO不会和这些非法字符混在一起。

    希望这能帮助别人。

    推荐文章