-
Notifications
You must be signed in to change notification settings - Fork 0
MS_PathLengthAndEncoding
-
TOP > インフラストラクチャ > Windows > Windows OSの基礎的トピック > ファイルシステム
- ファイルやパスの文字列長と文字コードの問題
- ファイル・サイズとディスク使用領域の不一致
-
GitHub のリポジトリに登録した物件をダウンロードした際、
取得した ZIP ファイルが解凍できないなどの問題があったので調査をしてみた。 -
ココの問題は、コンピュータに保存されているファイルの識別に用いられる「パス名」に起因する。
- パス名は,ドライブ文字、ディレクトリパス、ファイル名などを一定の記法に従って連結して表記したもの。
- Windows のパス名には少々複雑な事情があり、さまざまな注意が必要。
以下の2つの要因がある(実はファイルシステム側の問題ではなかった)。
Windows の後方互換でパス長の制限があるためパス長の制限があるソフトウェアが現存する。
-
NTFS ファイルシステムが 32K 文字までのパスをサポートしている。
-
しかし、Windows API は、後方互換性を重視するため、
- パス最大長が
MAX_PATH環境変数で 260 文字に設定されている。 - パスに
\\?\接頭辞を使用すると、260 文字を超える文字を使用できる。 - しかし、一部の Win32 API では
\\?\接頭辞を使用しても制限が解除されない。
- パス最大長が
というトコロに原因があるもよう。
- Windows 10 Version 1607 以降、
MAX_PATHの制限を解除できる。- レジストリ修正
- 若しくは、グループポリシー
移行メモ(用語):
MAX_PATHは環境変数ではなく
Windows SDK のヘッダーで定義されている定数(260)である。
「環境変数」は誤りだが、著者の言わんとする
「API 側に固定的な上限がある」という趣旨は変わらないため、
記述を残したうえでここに注記する。
補足(制限解除は 3 つ揃って初めて効く): Windows 10 1607 以降の
長いパスの有効化は、次の 3 つが揃って初めて機能する。
- レジストリ
HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled= 1
(またはグループ ポリシー「Win32 の長いパスを有効にする」)- アプリケーションのマニフェストに
longPathAwareの宣言があること- その API が長いパスに対応していること
「レジストリを変えたのに直らない」の多くは 2 が原因である。
なお\\?\接頭辞を付ける方法は 1 や 2 がなくても使えるが、
相対パスや./..が解釈されなくなる(後述の「サービス機能」の不活性化)。
例えば以下のような例。
- インテル ソフトウェア開発製品 日本語環境でのご注意 | XLsoft エクセルソフト Intel
https://www.xlsoft.com/jp/products/intel/tech/win_jp_limitation.html-
プログラム中のファイル入出力について、
フォルダー名に日本語を含むと正常に動作しない。 -
Microsoft Visual Studio 上でのデバッグ操作において、
- フォルダー名に日本語がある場合や、
- ソースコードのファイル名に日本語を含むと、
ブレークポイントが機能しない
-
, etc.
-
補足(原因は Unicode 版 API を使っていないこと): Windows の API は
ANSI 版(...A)と Unicode 版(...W)が対になっている。
ANSI 版はシステム ロケールのコードページで文字を解釈するため、
日本語環境では Shift_JIS(CP932)として扱われ、
「表」「ソ」など 2 バイト目が0x5C(\)になる文字で
パスの区切りを誤認する、といった不具合が起きる。
Windows 10 1803 以降は「ワールドワイド言語サポートで
UTF-8 を使用」というベータ機能でコードページを UTF-8 にできるが、
古いアプリが逆に動かなくなることがあるため注意が必要。
詳しくは「文字コード」を参照。
-
パスを短くする。
出力パスが短くなるようにする。
=圧縮した一式の解凍先をC:\tempなどとする。 -
パスの全角文字を除く。
以下のようなトピックもある模様。
- パス名の解釈に伴う「サービス機能」がある。
-
CreateFile()にはいくつものサービス機能がある。
- ディレクトリ区切り文字
/が使用できる。 - ディレクトリ区切り文字の重複
\\が許される。 - パス名の途中に
\.\を差し挟める。 - パス名の途中に
\..\を差し挟める。 - パス名の末尾の
.や半角スペースが無視される。
\\?\ から始まるパス名についてはサービス機能が働かなくなる。
補足(
\\?\の副作用): 上記のとおり、\\?\を付けると
パスの正規化が一切行われなくなる。
絶対パスでなければならず、/も使えないため、
長いパス対策として機械的に付けると別の不具合を招くことがある。
逆に、5 の「末尾の.や空白が無視される」性質を利用すると、
\\?\経由でしか削除できない不正な名前のファイルを作れてしまう。
Windows のファイルやディレクトリは
- ロングネームと
- そのロングネームから自動生成されたショートネーム(8.3形式)
の2つを持つ。
レジストリの NtfsDisable8dot3NameCreation で自動生成を OFF にできる。
- パス名に
~が含まれていたらショートネームが混入されていると見なす。 - API でショートネームをロングネームに変換するようにする。
補足(無効化は既存の名前を消さない):
NtfsDisable8dot3NameCreationを
有効にしても、すでに生成済みのショートネームは残る。
既存分を消すにはfsutil 8dot3name stripを使う。
古いアプリやインストーラーがショートネームに依存していることがあるため、
一括削除は事前確認が必要。
ファイル名に : が含まれていると具合が悪い。
- ファイル名中の
:は「ADS」を表す区切り記号として意味を持つため。 - 詳しくは、代替データストリーム(ADS)の仕様を参照。
-
MS-DOS の時代に用いられていた古典的な名称
- コンソール
- シリアル通信ポート
- プリンタポートなど
-
次の名前はディレクトリやファイルの名前には使ってはならない
AUXCONNULPRNCLOCK$-
COM1〜COM9 -
LPT1〜LPT9
-
10 番以降のデバイス
先頭に\\.\を付ける。
補足(拡張子を付けても駄目): 予約デバイス名は
CON.txtのように拡張子を付けても予約名として扱われる。
Git や ZIP で Linux 側から作られたaux/のようなディレクトリが
Windows で展開できないのは、これが理由であることが多い。
-
ASCII.jp:Windowsのパス区切り文字は、
なぜ逆スラッシュになったのか?|Windows Info
http://ascii.jp/elem/000/001/763/1763591/ -
8-1. Windowsパス名の落とし穴
https://www.ipa.go.jp/security/awareness/vendor/programmingv1/b08_01.html
-
260文字のパスの長さ制限がWindowsに存在するのはなぜですか?
path - limit | CODE Q&A [日本語]
https://code.i-harness.com/ja/q/1cb101 -
Long Paths in .NET, [Kim Hamilton] – BCL Team Blog
- Part 1 of 3
https://blogs.msdn.microsoft.com/bclteam/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton/ - Part 2 of 3: Long Path Workarounds
https://blogs.msdn.microsoft.com/bclteam/2007/03/26/long-paths-in-net-part-2-of-3-long-path-workarounds-kim-hamilton/ - Part 3 of 3 Redux
https://blogs.msdn.microsoft.com/bclteam/2008/07/07/long-paths-in-net-part-3-of-3-redux-kim-hamilton/
- Part 1 of 3
-
Naming Files, Paths, and Namespaces (Windows)
https://msdn.microsoft.com/en-us/library/aa365247.aspx -
CreateFileW等のwin32apiでMAX_PATH 超のメモ - Qiita
https://qiita.com/jugemjugemu/items/4db1dfd3d2737d3979dfnet462 の Fix 260 character file name length limitation で、
System.IO API に長いパスのサポートが入った。
-
ファイル名の長さと文字コードの問題:
プログラマー社長のブログ:オルタナティブ・ブログ
http://blogs.itmedia.co.jp/komata/2012/11/post-85cf.html -
ファイル名・パス名の文字数制限と日本語名には注意が必要です。
|滋賀県大津市の小さなパソコン教室「ぱそこんる~む123」
https://ameblo.jp/pcroom123/entry-11545076070.html
-
長いファイル名を含むZIPファイルの解凍
'-とあるZIPファイルを解凍しよ- その他(ソフトウェア) | 教えて!goo
https://oshiete.goo.ne.jp/qa/1624421.html -
Zipファイルを展開しようとすると
「変更先へのパスが長すぎます、圧... - Yahoo!知恵袋
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1347271633 -
Windows XP で ZIP 形式のファイルを解凍すると、
"指定されたファイルが見つかりません" と
エラー メッセージが表示されてファイルの解凍ができない場合がある
https://support.microsoft.com/ja-jp/help/978341 -
IBM Knowledge Center
インストール・ファイルの解凍時における
「ファイル・パスが長すぎます (File path too long)」などのエラー
https://www.ibm.com/support/knowledgecenter/ja/SSFUEU_7.1.0/com.ibm.swg.ba.cognos.op_installation_guide.7.1.0.doc/c_in_trbls_uncompress_camphor.html
-
色々書き足して行こうと考えていたけど、良いネタが無いかも。
-
最近遭遇した、現象に、
-
フォルダ名に C# の
#が混在していると .NET Core の Build に失敗する。 -
roslyn の完全限定型名は 260 文字、ディレクトリ名は 248 文字以上だと失敗する。
--------------------------- Microsoft Visual Studio --------------------------- 式 "roslyn\%(RecursiveDir)%(Filename)%(Extension)" の中のメタデータを展開できません。 項目メタデータ "%(Filename)" をパス "....\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net46\ ..\..\tools\roslynlatest\System.Security.Cryptography.X509Certificates.dll" に適用できません。指定されたパス、ファイル名、またはその両方が長すぎます。 完全限定型名は 260 文字未満で指定し、ディレクトリ名は 248 未満で指定してください。
というモノがあった。
- 後者は「
#」→「S」で解決するけど、 - 前者はフォルダ構成を変更する必要がある。
-
移行メモ(対応関係): 上記の「後者は
#→Sで解決する」は、
直前の 2 つの箇条書きの**前者(#を含むフォルダ名)**への対処である
(後者はパス長の問題なので#の置換では解決しない)。
著者の記述をそのまま残したうえで注記する。
- 8.3形式 - Wikipedia
https://ja.wikipedia.org/wiki/8.3%E5%BD%A2%E5%BC%8F
ADS: Alternate Data Stream
-
ASCII.jp:インターネットからダウンロードしたファイルは
Zone.Identifierでセキュリティ管理をする|Windows Info
http://ascii.jp/elem/000/001/550/1550399/ -
フォーク (ファイルシステム) - Wikipedia
https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A9%E3%83%BC%E3%82%AF_(%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)
Tags: インフラストラクチャ, Windows
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。