web-dev-qa-db-ja.com

MAX_PATHより長いファイルを処理する必要がありますか?

興味深いケースがありました。

私のソフトウェアは、パスがMAX_PATHより長いために発生した障害を報告しました。

パスは、マイドキュメント内の単なる古いドキュメントでした。例:

C:\Documents and Settings\Bill\Some Stupid FOlder Name\A really ridiculously long file thats really very very very..........very long.pdf

全長269文字(MAX_PATH == 260)。

ユーザーは外付けハードドライブなどを使用していませんでした。これは、Windows管理ドライブ上のファイルでした。

だから私の質問はこれです。気にする必要がありますか?

私は言っていませんcan私は長い道のりを扱っています、私は尋ねていますshould I.はい私はいくつかの「\?」ユニコードハックを知っていますWin32 APIですが、このハッキングにはリスクがないわけではなく(APIがパスを解析する方法の動作が変わるため)、すべてのAPIでサポートされているわけではないようです。

とにかく、私の立場/主張を述べさせてください:

  1. 最初に、おそらくユーザーがこの制限を破ることができた唯一の方法は、使用したアプリが特別なUnicodeハックを使用するかどうかです。これはPDFファイルなので、彼女が使用したPDFツールはこのハックを使用している可能性があります。
  2. 私はこれを(ユニコードハックを使用して)再現しようとし、実験しました。私が見つけたのは、ファイルはエクスプローラーに表示されますが、それでは何もできないということでした。開くことができず、「プロパティ」を選択できません(Windows7)。他の一般的なアプリ(IE、Firefox、メモ帳など)はファイルを開くことができません。 Explorerでは、長すぎるファイル/ディレクトリを作成することもできません。拒否するだけです。コマンドラインツールcmd.exeについても同様です。

つまり、基本的には、このように見ることができます。ルージュツールを使用すると、ユーザーは多くのWindows(Explorerなど)からアクセスできないファイルを作成できます。私はこれに対処する必要はないはずだという見方をすることができました。

(余談ですが、これは短い最大パス長に対する承認の投票ではありません。260文字は冗談だと思います。Windowsシェルと一部のAPIが260を超える処理を実行できない場合、なぜ私がすべきなのかということです。 ?)。

それで、これは公正な見方ですか? 「私の問題ではない」と言うべきですか?

PDATE:同じ問題を抱えている別のユーザーがいます。今回はmp3ファイル。私は何かが足りないのですか?これらのユーザーは、MAX_PATHルールに違反するファイルをどのように作成できますか?

30
John

それは本当の問題ではありません。 NTFSは、最大32K32,767ワイド文字)のファイル名をサポートします。正しいAPIとファイル名の正しい構文を使用するだけで済みます。基本ルールは次のとおりです。ファイル名は'\\?\'で始まる必要があります( http://msdn.Microsoft.com/en-us/library/aa365247(v = VS.85).aspx を参照) )\\?\C:\Tempのように。 UNCで使用できるのと同じ構文:\\?\UNC\Server\share\Path。 API関数のごく一部しか使用できないことを理解することが重要です。たとえば、MSDNの関数の説明を見てください

CreateFile
CreateDirectory 
MoveFile

等々

あなたは次のようなテキストを見つけるでしょう:

この関数のANSIバージョンでは、名前はMAX_PATH文字に制限されています。この制限を32,767ワイド文字に拡張するには、関数のUnicodeバージョンを呼び出し、パスの前に「\?」を付けます。詳細については、ファイルの命名を参照してください。

安全に使用できる機能です。 CreateFileのファイルハンドルがある場合は、hFileReadFileWriteFileなど)で使用される他のすべての関数を制限なく使用できます。

ウイルススキャナーやバックアップソフトウェア、またはサーバー上で実行されるいくつかの優れたソフトウェアなどのプログラムを作成する場合は、すべてのファイル操作が最大32K文字のファイル名をサポートするようにプログラムを作成する必要があります。 MAX_PATH文字。

12
Oleg

この制限は、CまたはC++で記述されたソフトウェアのlotに組み込まれています。 MSFTコードを含みますが、それらはそれを削っています。これは部分的にのみWin32の制限であり、たとえばWIN32_FIND_DATAを介したファイル名(パスではない)の長さには依然として厳しい上限があります。 .NETでさえ 長さ制限 がある理由の1つ。これはすぐになくなることはなく、Win32は引き続き強力であり、石器時代のCストリングは消えません。

おそらく、同じように失敗する別のプログラムを顧客に示すことができるまで、顧客はそれにほとんど共感しないでしょう。ただし、コードが潜在的な文字列バッファオーバーフローを確実に検出できることを確認してから、適切な診断を行ってください。ヒープの破損を爆撃するプログラムには同情はありません。

10
Hans Passant

おっしゃるように、Windowsシェル関数の多くはMAX_PATHまでのパスでのみ機能します。 Windows XPそして私はVistaの両方が長いファイル名のディレクトリをネストするときにエクスプローラーで問題があると思います。私はWindows7をチェックしていません-おそらく彼らはそれを修正しました。これは残念ながらユーザーが苦労していることを意味しますこれらのファイルを閲覧する時間。

本当に長いパスをサポートしたい場合は、パスを取るShell32.dllで使用している関数をチェックして、長いパスをサポートしていることを確認する必要があります。そうでない場合は、Kernel32関数を使用して自分で作成する必要があります。

Shell32を使用し、MAX_PATHに制限する場合は、長いファイルパスをサポートするようにコードを作成することをお勧めします。 Microsoftが後でShell32を変更する(または代替を作成する)場合は、それらのサポートを追加するのに適した立場になります。

問題にさらにいくつかの次元を追加するために、ファイル名はUTF-16であり、大文字と小文字が区別される非NTFSまたはFATファイルシステムに遭遇する可能性があることに注意してください。

6
Stephen Nutt

独自のAPIは、パスの長さの固定制限(またはその他のハード制限)をハードコーディングしないでください。ただし、いくつかのタスクを実行するために、システムAPIの前提条件に違反しないでください。私見ですが、Windowsがパス名の長さを制限しているという事実はばかげているので、バグと見なす必要があります。とはいえ、最大パス長の制限など、特定の望ましくない動作が発生したとしても、文書化されている以外のさまざまなシステムAPIを使用しないことをお勧めします。つまり、あなたの見解は完全に公正です。 OSがそれをサポートしていない場合、OSはそれをサポートしていません。とはいえ、これはWindowsの制限であり、独自のコードの制限ではないことをユーザーに明確にしたいと思うかもしれません。

MAX_PATHより長いパスをサポートしないソフトウェアでも、パスが長いこれらのファイルを簡単に作成する方法の1つは、ファイル共有を使用することです。

例:

「C:\ Myveeeeeeeeeeeeeeeeeeeeerylooooooooooooooooooongfolder」は「data」として共有できます。ユーザーは、UNCパス\\ computer\dataを介して、または(さらに短い)ドライブ文字(M:\)を介して、M:が\\ computer\dataにマップされていると仮定して、そのフォルダーにアクセスできます。

これはファイルサーバーでよく発生します。

2
Helge Klein

私はいくつかのCプログラミングを行っており、指定されたファイル名の最大長を取得する方法を探していました。MAX_PATHを検索した後、このスレッドに遭遇し、この問題について考えた後、このスレッドのコメントを読んだ後、次の結論に達します。

したがって、NTFSは最大32.767文字の長さのファイル名をサポートすることを理解していますが、知識によれば、FAT16は8 + 3の11文字のファイル名しかサポートしないため、実際のオペレーティングシステムには、プログラムが呼び出して最大ファイル名サイズを決定できる関数が必要です。 、ファイル名の長さなど、すべてのファイルシステムに異なる制限があるからです。

したがって、最終的な結論は、開発者である私たちがデータが格納されるファイルシステムについて何も知らないため、唯一の解決策は試行錯誤の方法でなければならないということです。

1
Ivo Santos

多くの場合、パスは260より大きくなる可能性があります。たとえば、シンボリックリンクがネストされ、意図的にでも何度も繰り返される場合があります。プログラマーは、プログラムでこれらのめちゃくちゃ大きなパスを処理するかどうかを考える必要があると思います。 IMO、260は十分なスペースですが、それは私だけです。これに対する私の答えは:

260文字の制限を超えることについて深く自問する必要がある場合は、おそらくそれを行う必要があります。不明なことを実行しようとしているときに、確認を探すことがよくあります...

APIのどこでも最大パスは約32kの長さだと思いますが、それはあなた次第です。当時はかなり大きな変化でしたが(メモリセグメント全体の半分!!シーシュ!)、今日では、すべてのメモリがフラットな32kに積み上げられている、私たちが住んでいるセグメント透過的なアドレス指定環境でis nothin '... AFAIKパスは、他の多くの文字などを必要とする派手なUnicode言語を使用していない限り、それほど長くする必要はありません。これについては1日中説明できますが、アイデアは得られます。私はこれが役立つことを願っています.....または痛いですか?

1
osirisgothra

特定の質問に対する厳密な回答ではありませんが、長いファイル名を処理する必要がある人には役立つ可能性があります。

Delimonライブラリは、長いファイル名の問題を克服するためのMicrosoftTechNet上の.NETFramework4ベースのライブラリです。

Delimon.Win32.I Oライブラリ(V4.0)

System.IOの主要なメソッドの独自のバージョンがあります。たとえば、次のように置き換えます。

System.IO.Directory.GetFiles

Delimon.Win32.IO.Directory.GetFiles

これにより、長いファイルやフォルダを処理できるようになります。

ウェブサイトから:

Delimon.Win32.IOは、System.IOの基本的なファイル機能を置き換え、最大32,767文字のファイルとフォルダーの名前をサポートします。

このライブラリは.NETFramework 4.0で記述されており、x86およびx64システムのいずれかで使用できます。標準のSystem.IO名前空間のファイルとフォルダーの制限は、ファイル名が260文字、フォルダー名が240文字のファイルで機能します(MAX_PATHは通常260文字として構成されます)。通常、標準の.NETライブラリでSystem.IO.PathTooLongExceptionエラーが発生します。

0
TripleAntigen