1. ホーム
  2. c#

[解決済み] 259文字以上のファイル名を持つファイルを処理する方法は?

2023-01-02 12:34:24

質問

私は、いくつかのディレクトリ内のすべてのファイルを走査し、それらのファイルに対していくつかのアクションを実行するアプリケーションに取り組んでいます。とりわけ、私はファイルサイズとこのファイルが変更された日付を取得する必要があります。

いくつかのファイルのフルネーム (ディレクトリ + ファイル名) が長すぎるため、.NET Framework の FileInfo に制限されている MAX_PATH (260文字)に制限されています。多くの Web ソースでは、名前が長すぎるファイルにアクセスするために、P/Invoke を使用してネイティブの Win32 関数を使用することを勧めています。

現在、まったく同じ問題が Win32 関数で発生しているようです。たとえば GetFileAttributesEx (kernel32.dll) は、270 バイトのパスに対して Win32 エラー 3 ERROR_PATH_NOT_FOUND で失敗します。

まったく同じファイルをメモ帳2から正常に開くことができ、Windows エクスプローラーで正常に表示できます (しかし、たとえば Visual Studio 2010 では 259 文字の制限¹ のために開くことができません)。

ファイルパスが 270 文字の場合、ファイルにアクセスできるようにするにはどうしたらよいでしょうか。

注意事項

  • ファイルパス長が 259 文字を超えるファイルを削除または無視することは、解決策にはなりません。

  • Unicode 互換のソリューションのみを探しています。

  • アプリケーションは、.NET Framework 4 がインストールされた Windows 2008/Vista またはそれ以降の環境で動作します。



驚くことに、Microsoft Word 2007 は、フロッピー ドライブがないコンピュータではフロッピー ディスクが小さすぎるとか、4 GB の RAM が残っているのに RAM メモリが少ないとか、最後にアンチウイルス ソフトウェアを更新する必要があるとか言って、エラーになります。少なくとも Microsoft Office のような主要製品において、このような愚かで無意味なエラーを表示するのはいつか止められるのでしょうか?

どのように解決するのですか?

.NET 4.6.2での解決方法

を使用します。 \\?\C:\Verrrrrrrrrrrry long path の構文で記述します。 ここで .

.NET Coreソリューション

フレームワークが長いパスの構文を追加してくれるからうまくいくだけです。

.NET 4.6.2 以前の解決策

また、ロングパス構文 とP/InvokeによるWin32 API関数のUnicodeバージョンを使用します。 から ファイル、パス、およびネームスペースの命名 :

Windows API には、最大合計パス長 32,767 文字の拡張長パスを許可する Unicode 版もある多くの関数があります。このタイプのパスは、バックスラッシュで区切られたコンポーネントで構成され、それぞれが GetVolumeInformation 関数の lpMaximumComponentLength パラメータで返される値 (この値は通常 255 文字) までの長さになっています。 拡張長のパスを指定するには \\?\ というプレフィックスを使用します。例えば \\?\D:\very long path .

読書 このマイクロソフト サポート ページ も興味深いかもしれません。

非常に広範な説明が .NET におけるロングパス by Kim Hamilton at the BCL Team blog にあります。 は、この構文がまだ .NET で直接サポートされていない理由であると主張する、これらのパスの処理におけるいくつかの不具合をリストアップしています。

過去に長いパスを追加することに消極的だった理由と、今でもそれについて慎重である理由がいくつかあります。

<...> は \\?\ プレフィックスは長いパスを可能にするだけでなく、Windows API による最小限の変更でパスをファイル システムに渡すようにします。その結果 \\?\ は Windows API によって実行されるファイル名の正規化 (末尾のスペースの削除、'.' と '...' の展開、相対パスのフルパスへの変換など) を無効にすることです。

<...> ロング パスを \\?\ のプレフィックスを持つ長いパスは、ほとんどの ファイル関連 で使用できますが、すべてのWindows APIではありません。例えば、LoadLibrary<...> はファイル名が MAX_PATH より長いと失敗する。 <...> Windows API の至る所に同様の例がある。

もう一つの要因は、他の Windows ベースのアプリケーションや Windows シェル自体との互換性です。

この問題はますます一般的になってきているため、Microsoft 全体でこの問題に対処するための取り組みが行われています。実際、Vista のタイムリーなプラグインとして、MAX_PATH の制限に達する可能性を減らすいくつかの変更に気づくでしょう。特殊なフォルダー名の多くが短くなり、さらに興味深いことに、シェルは自動パス縮小機能を使って 260 文字に縮小しようと試みます。


警告です。.NET Framework がこの種のパス構文をサポートしていない可能性があるため、Windows API を直接呼び出す必要があるかもしれません。