有効な絶対パスとファイル名を保持するのに十分な大きさを保証されたchar配列(Cで)を割り当てたい場合、どのくらいの大きさが必要ですか。
Win32には、MAX_PATH定義があります。 Unix/linuxに相当するものは何ですか?
PATH_MAX
、しかし少し問題があります。 realpath(3) manページのバグセクションから:
この関数のPOSIX.1-2001標準バージョンは、出力バッファーresolved_pathに適切なサイズを決定することが不可能であるため、設計により壊れています。 POSIX.1-2001によると、サイズPATH_MAXのバッファーで十分ですが、PATH_MAX定義済みの定数である必要はなく、 pathconf(3) を使用して取得する必要があります。そして、 pathconf(3) を求めることは、実際には役に立たない。なぜならPOSIXは pathconf(3) の結果が巨大でメモリの割り当てに適していない可能性があると警告しているため、一方、 pathconf(3) は-1を返し、PATH_MAXが制限されていないことを示します。
これまでの他の答えは、物事の* nix側については正しいと思われますが、Windowsについては警告を追加します。
あなたはドキュメンテーションに(省略によって)嘘をついた。
MAX_PATH
は実際に定義されており、おそらくFATまたはFAT32に保存されているファイルにも適用されます。ただし、任意のパス名の前に\\?\
を付けると、Windows APIにMAX_PATH
を無視して、ファイルシステムドライバーが独自の判断を下すように指示できます。その後、定義はあいまいになります。
パス名が実際にはユニコード(まあ、UTS-16)であり、「ANSI」APIが使用される場合、内部ユニコード名との間の変換は、現在のコードページを含む一連の要因に依存するという事実を追加してください、混乱のレシピがあります。
Windowsのルールの適切な説明は [〜#〜] msdn [〜#〜] にあります。ルールは、ここで要約したよりもはるかに複雑です。
編集:KitsuneYMGからのコメントのおかげで、上記の\\.\
を\\?\
に変更しました。
Windowsのパスと名前空間は複雑です。複雑すぎると主張する人もいます。複雑さの原因の1つは、Win32(および現在はWin64)APIがWindows NTネイティブシステムの上にあるサブシステムであるということです。
プレフィックスのないパスは、最も広範なWindowsプラットフォーム間で互換性があります。 7ビットASCII文字に制限されている場合、バージョン2.0以降の16ビットDOSと互換性があります(サブディレクトリが導入された場合は、実際にDOS 3にあった可能性がありますが、 DOS 1.0にはルートディレクトリのみがあり、\
文字には特別な意味はありませんでした)。
\\?\
プレフィックスにより、パス名の残りの部分が適切なファイルシステムドライバーにそのまま渡されます。これにより、制限がMAX_PATH
文字にドロップされます。長いパス名もネットワーク共有上にある場合は、通常のUNC名\\?\UNC\server\share\
の代わりに、プレフィックス\\server\share\
を使用して拡張UNC名を使用できます。このプレフィックスを使用すると、Win32以降のWindowsプラットフォームへの移植性が制限されますが、レガシーハードウェアで16ビットWindowsのサポートが必要でない限り、それは大きな問題ではありません。
\\.\
プレフィックスは別の動物です。 Windowsによってすべてのファイルフォルダーに特別なファイル名として自動的にマッピングされる、特別な名前のデバイスのセットを超えて、デバイスオブジェクトにアクセスできます。これらの特別な名前には、CON、PRN、AUX、NUL、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8、およびLPT9が含まれます。これらの名前はすべて、拡張子が使用されているかどうかにかかわらず、または大文字と小文字が混在していても特別です。ただし、10個以上のCOMポートがインストールされている可能性があります。これは、USBモデムまたはUSBシリアルポートアダプターを使用すると、一意の各USBベースのシリアルポートに個別のCOMn名が割り当てられるため、すぐに発生します。 50番目のシリアルポートにアクセスする必要がある場合、COM50はnotCOM1のような特別な名前なので、\\.\COM50
という名前でのみアクセスできます。
上記で引用したMSDNページには区別権があり、元の回答に間違ったプレフィックスを入力しただけです。
まあ、少なくともLinuxでは、次のものがあります。
PATH_MAX
(limits.h
で定義)
FILENAME_MAX
(stdio.h
で定義)
私のシステム(x86 Linux)では、これらは両方とも4096
に設定されています。
更新:: これに関するglibcマニュアルの情報
次の各マクロは、システムが問題のパラメーターに対して固定された一定の制限を持っている場合にのみ、limits.hで定義されます。システムが異なるファイルシステムまたはファイルに異なる制限を許可している場合、マクロは未定義です。 pathconfまたはfpathconfを使用して、特定のファイルに適用される制限を見つけます
FILENAME_MAXはISO C標準の一部であり、UNIXおよびWindowsで機能します。ただし、GNU Cライブラリのドキュメントには、次の警告が含まれています。
「PATH_MAXとは異なり、このマクロは実際に制限が課されていなくても定義されます。そのような場合、その値は通常非常に大きな数です。これは常にGNUシステムに当てはまります。
使用上の注意:ファイル名を格納する配列のサイズとしてFILENAME_MAXを使用しないでください!配列をそれほど大きくすることはできません!ダイナミックアロケーションを使用します。」
pathconf()
を使用して実行時に把握できますが、<limits.h>
にはPATH_MAXプリプロセッサ定義もあります。
realpath
関数を使用して、特定のパスに十分な大きさのバッファーを割り当てることができます。 2番目の引数としてNULLポインターを渡すと、パスに十分な大きさのバッファーが割り当てられます。おそらくmanページは私ができるよりもそれをよく説明しています:
realpath()はすべてのシンボリックリンクを展開し、/。/、/ .. /、およびpathで指定されたヌル終了文字列内の余分な「/」文字への参照を解決して、正規化された絶対パス名を生成します。結果のパス名は、resolved_pathが指すバッファーに、最大PATH_MAXバイトまでのヌル終了ストリングとして保管されます。結果のパスには、シンボリックリンク、/。/または/../コンポーネントはありません。
resolved_pathがNULLとして指定されている場合、realpath()はmalloc(3)を使用してPATH_MAXバイトまでのバッファーを割り当て、解決されたパス名を保持し、このバッファーへのポインターを返します。呼び出し元は、free(3)を使用してこのバッファーの割り当てを解除する必要があります。
limits.h
/*
* File system limits
*
* NOTE: Apparently the actual size of PATH_MAX is 260, but a space is
* required for the NUL. TODO: Test?
* NOTE: PATH_MAX is the POSIX equivalent for Microsoft's MAX_PATH; the two
* are semantically identical, with a limit of 259 characters for the
* path name, plus one for a terminating NUL, for a total of 260.
*/
#define PATH_MAX 260
minwindef.h
#define MAX_PATH 260