3

有効なパスが C:\Users\David の Vista マシンで Directory.GetFiles(@"C:\Users\David") を呼び出すと、ディレクトリの内容を表示できる David ユーザーとして実行すると、次の ArgumentException がスローされます。 Windowsエクスプローラーで問題ありません:

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 からアクセスされたため、ディレクトリには「._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全体でファイルを見ると、ファイルの名前は実際には「._Icon?」のようです。Mac からファイルを削除しようとするたびに、ファイルがすぐに再表示されるようです。

4

4 に答える 4

1

PInvoke FindFirstFileを使用してファイルの一覧を表示してみてください。ここを参照してください。類似の問題を引き起こしますか?

ファイル情報は、WIN32 FIND DATA 構造体で返されます。次に、0 が返されなくなるまで、各ファイルに対してFindNextFileを呼び出します。構造体では、cFileName メンバーを使用してファイル名を取得できます。そこに何が無効かを確認してください。

私のポイントは、これが Directory.GetFiles が吐き出すファイル情報を返す可能性があるということです。

以下はその使用例です。

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]
于 2009-05-28T11:28:48.573 に答える
1

参考までに、表示されているのはリソース フォークです。これらは Windows リソースとは大きく異なり、NTFS 代替データ ストリームにほぼ類似しています。

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

リソース フォークは、Macintosh のシステム ドライブに使用されるすべてのファイル システム (MFS、HFS、および HFS Plus) に実装されています。リソース フォークの存在により、システムがファイルの正しいアイコンを表示し、ファイル名にファイル拡張子を必要とせずにファイルを開くことができるようにするなど、さまざまな追加情報を簡単に保存できます。データ フォークへのアクセスは、他のオペレーティング システムでのファイル アクセスと同じように機能しますが (ファイルを選択し、バイト オフセットを選択し、データを読み取ります)、リソース フォークへのアクセスは、データベースから構造化されたレコードを抽出するように機能します。

Microsoft sysinternals サイトから:

NTFS ファイル システムは、情報の代替データ ストリームを作成する機能をアプリケーションに提供します。デフォルトでは、すべてのデータはファイルのメインの名前のないデータ ストリームに格納されますが、構文「file:stream」を使用することで、別のデータ ストリームを読み書きすることができます。すべてのアプリケーションが代替ストリームにアクセスするように作成されているわけではありませんが、ストリームを非常に簡単に示すことができます。まず、コマンド プロンプトから NTFS ドライブ上のディレクトリに移動します。次に、「echo hello > test:stream」と入力します。ファイル「test」に関連付けられた「stream」という名前のストリームを作成しました。test のサイズを見ると 0 と報告されており、テキスト エディターでファイルを開くとファイルが空に見えることに注意してください。ストリームを表示するには、「more < test:stream」と入力します (type コマンドは「

于 2010-08-02T18:51:08.850 に答える
0

これが少し古くなっていることは承知していますが、Windows から OSX ファイル システムにアクセスする際にまったく同じ問題が発生しました。DotNet から「不正なファイル名」エラーが表示されます。原因は、icon という名前の 0 バイトの Mac ファイルでしたが、ファイル名の末尾に四角形がありました。

私の解決策は、少しの VB6 コードと interop.scripting filesystemobject を使用して、そのようにファイルをリストすることでした。

FSO は、これらの不正な文字を処理しません。

それが誰かを助けることを願っています。

于 2010-11-01T02:24:40.287 に答える
0

ファイルを削除するか、名前を変更してみてはどうでしょうか。

真剣に、これは「修正」するために特別なケースのコードを書く価値があるほど頻繁に発生しますか?

于 2009-05-27T14:41:54.953 に答える