isLandcenter 非番中

ブログトップ | ログイン

ファイル名とパスの最大長の色々

ファイル名とファイルパスの最大長について。

Samba にファイルを保存しようとしたら、「ファイル名が長すぎる」と怒られたので、ファイルサーバーで保存するファイル名の長さ、トータルのパスの長さを調べてみました。
ここでは Samba だけではなく、Windowsや macOS のファイル名、パスの長さ制限についても調べました。


- SUSE Linux(openSUSE Leap 15.1)-

SUSE に限らず多くの Linux ディストリビューションや UNIX 系では getconf コマンドで NAME_MAX を調べてみると良いでしょう。 255 バイトで、最後の一文字は NULL なので、実質 254 バイトになるはずです。誤っていたらコメントください。これは posix 準拠のためなんでしょうね。

sle15:~ # getconf -a | grep NAME
NAME_MAX                           255
_POSIX_NAME_MAX                    255
LOGNAME_MAX                        256
TTY_NAME_MAX                       32
TZNAME_MAX
_POSIX_TZNAME_MAX
CHARCLASS_NAME_MAX                 2048
HOST_NAME_MAX                      64
LOGIN_NAME_MAX                     256
sle15:~ #

IBM の資料ですが、getconf の詳細はこちらをご参考ください。
getconf — 構成値を取得する

Samba や NAS などでは 255 「バイト」、Windows では260「文字」。長いファイル名は Samba では使えないわけです。

長いファイル名を扱うことができない

ただし、これは「ファイル名の制限」で、limits.h によるとパスも含める 4096 バイトの様です。これはファイルシステムフォーマットの問題ではなくシステムAPIによる制限です。


最大パスサイズは「バイト」で日本語でパスを作成する場合、UTF8 では3~4バイト使うため、「日本語の文字数」に注意が必要です。

opensuse151:~ # cat /usr/include/linux/limits.h | grep PATH
#define PATH_MAX        4096    /* # chars in a path name including nul */

opensuse151:~ # getconf -a |grep PATH
PATH_MAX                           4096
_POSIX_PATH_MAX                    4096
PATH                               /bin:/usr/bin
CS_PATH                            /bin:/usr/bin
opensuse151:~ #


実際にプログラムを書いて試したヒトがいました。中々面白いプログラムです。

Check File Systems maximum path depth

Now run it:
$ time ./createDirectories

return code     : -1
Created sub-directories : 1018
length of pathname  : 4096

real    0m0.281s
user    0m0.004s
sys 0m0.180s


私の openSESE Leap 15.1 の環境では若干違いがありました。

opensuse151:~/test # ./ptest
return code             : -1
Created sub-directories : 1022
length of pathname      : 4098

1023 バイト説もありますが、その根拠が分かりませんでした。コメントいただけると幸いです。

- Novell NSS はパスも含めて 1023の Unicode 文字 - 

ファイルサーバー専用OSの Novell Open Enterprise Server (OES)では、ファイル名そのものは16ビット Unicode で 255 文字、フルパスは 1023 文字です。

6.4 Naming NSS Storage Objects

6.4.2 Number of Characters Allowed
For the NSS file system, the maximum length supported for a filename (the name and file extension) is 255 16-bit Unicode characters. The maximum length supported for the full path name (which includes the volume name, directories, filename, extension, and delimiters in the path) is 1023 16-bit Unicode characters.

However, different tools, applications, and file systems place different limits on filenames and path lengths, some of which can be more or less restrictive than these limits.

16bit Unicode でパスも含めて 1023 文字です。もっとも、それだけの長さを扱えるソフトウェアやアプリケーションがあるとは限らないのでマウントしたシステムによる、という事です。標準的なシステムより、長いパスを作ってマルチベンダー対応、という事なのですが、良くある話でマルチベンダー固有のトラブルも抱えます。

なお、上の記事は、OES2018 のNSSなので OES2 以前のバージョンや NetWare カーネルでは 255 文字という記述もありました。多分ファイル名だけの制限でしょう。

- Windows NTFS -

NTFS の概要

拡張パスのサポート: 多くの Windows API 関数には、MAX_PATH 設定で定義された 260 文字のパスの上限を超える約 32,767 文字の拡張パスを許可する Unicode バージョンがあります。
 
最大 32,767 文字が MAX_PATH 変数によって 260 文字(パスも含む)に制限されています。この数値は Win32 の制限によるもので、グループポリシーで変更できます。

> gpedit > コンピュータの構成 > 管理用テンプレート > システム > ファイルシステムに "Win32の長いパスを有効にする" を有効にして > gpupdate を実行します。

ファイル名とパスの最大長の色々_a0056607_13581623.png

例えば、サーバー上の "D:\(フルパス含めて全部で260文字).txt" をネットワーク共有で "\\server\my-long-share\(共有名を含めると260文字超えちゃった).txt" でアクセスする場合などにはこの制限を撤廃すべきでしょうか。やはり「255文字前後が一般的な壁」なので、濫用は要注意です。

バックアップからのリカバリなどでも、このファイル名の長さ制限でリストアできないファイルがある場合も考えられます。
Windows Server -> Samba でバックアップエラーが起こるとややこしい事になりそうですね。 

Linux側では、4096(NULL含) のパスの長さなので、 Unix 系OSや macOS とファイル共有すると、ファイル名の長さで Windows からアクセスできないケースも出てくるわけです。

- MacOS HFS+ -

Wikipedia によると

最大ファイル名長
255文字(UTF-16での文字数。Appleが改変したUnicode正規化形式Dに正規化される)
https://ja.wikipedia.org/wiki/HFS_Plus

残念ながら、パスを含んだ最大の数字は見つからなかった...ので getconf してみました。 

etesian-mini:etc uhoge$ uname -a
Darwin etesian-mini.local 19.0.0 Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64 x86_64
etesian-mini:etc uhoge$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.1
BuildVersion: 19B88
etesian-mini:etc uhoge$ getconf NAME_MAX /
255
etesian-mini:etc uhoge$ getconf PATH_MAX /
1024
etesian-mini:etc uhoge$

ファイル名とパスの最大長の色々_a0056607_12410148.png

どうも macOS X 10.15.1 では、ファイル名の長さは 255(NULLを除いて254)バイト、最大パスは 1024 ということになりそうです。

古いHFSの場合は31文字です。また、AFP を使う時も 31 文字のよう。








- まとめ -

色々調べてわかったのは....

- 大体のシステムでは2020 年現在 255 文字前後のUTF16、またはバイトが、ファイル、ディレクトリ名で使える
- バイトの場合と UTF16 の場合がある。
- Unix 系システムでは、ディレクトリパスも含めて、4095(+null) で 全部で4096バイトのようだ
- Unix 系システムで Samba を使う場合、長いパスは Windows からアクセスできない場合がある。
- ただし OS が扱うファイル名の文字コードが UTF16 であるとは限らない。最近は大抵 UTF8 だったりする
- Windows10 系は 260 文字だが、「初期の Windows は 254" バイト"」だったりでバージョンによってはバラバラ。
- Windows10 系のパスの長さ制限は「拡張パス」という秘密の扉を開けると32,767 文字まで使える
- システムが使う文字コードが Shift-JIS だったり、Unicode だったり、UTF-8 だったり EUC だったりするとどうなるか不明
- 日本語コードに慣れたプログラマとはトモダチにになっておくべきだ。
- バイト数と UTF16、UTF8、の「文字数」とは違う事をエンドユーザに説明するのはインド人にウナギを食わせるくらい難しい
- 特に文字数とバイト数の違いに注意。chars が、いわゆる char 変数なのか、文字通りの「非アルファベット」の複数バイトの文字数(letter数)なのか
- 職場を辞めたヤツが、Mac からファイルサーバーの日本語フォルダの深さをチャレンジ、しかも読み込み専用のフラグを立てて退職したことを思い出した。頭にきた。
- 長くて深いディレクトリ名、ファイル名をユーザは使わないで欲しい。ってか、よくそんな面倒なことするなよ。
- ファイルシステムに制限がなくても(no limit) OS の API 制限に引っかかることが多い。Windows のエクスプローラは「アプリケーション」である。
- アプリケーションからアクセスできないファイルは夜作られる。
- ファイル名とパスの長さは、誰か Wikipedia に記事を書いてまとめて欲しいくらい、面倒である。





他にも文字コードの違いや機種依存文字、使えない記号符号特殊文字などもあります。これはまた別の機会に調べてみます。





by islandcenter | 2020-02-24 14:12 | SUSE | Comments(0)