ファイル名エンコーディングがどのように機能するかを理解するのに苦労しています。 unix.SEで私は矛盾する説明を見つけます。
別の回答を引用するには: Linuxでのファイルシステムの文字エンコードに関するいくつかの質問
[…]質問で述べたように、UNIXファイル名は文字のシーケンスにすぎません。カーネルはエンコーディングについて何も知りません。これは完全にユーザー空間(つまり、アプリケーションレベル)の概念です。
ファイル名が文字として格納される場合、最終的にファイル名がディスク上でビットまたはバイトシーケンスになるため、何らかのエンコードが必要になります。ユーザーがanyエンコーディングを選択して、カーネルに供給されるバイトシーケンスに文字をマッピングできる場合、有効なファイル名にanyバイトシーケンスを作成できます。
次のように仮定します。ユーザーはランダムなエンコード[〜#〜] x [〜#〜]を使用して、ファイルを変換しますfoo
バイトシーケンスαに入れて、ディスクに保存します。別のユーザーがエンコードを使用しています[〜#〜] y [〜#〜]。このエンコーディングでは、αは/
に変換され、ファイル名としては許可されません。ただし、最初のユーザーのファイルは有効です。
このシナリオは起こり得ないと思います。
別の答えを引用するには: Linuxでファイル名とパスに使用されている文字セットエンコーディングは何ですか?
他の人が指摘したように、これに対する答えは実際にはありません。ファイル名とパスにはエンコードがありません。 OSはバイトシーケンスのみを扱います。個々のアプリケーションはそれらを何らかの方法でエンコードされていると解釈することを選択できますが、これは異なります。
システムが文字を処理しない場合、特定の文字(/
またはNULL
など)をファイル名でどのように禁止できますか?エンコーディングなしの/
の概念はありません。
ファイルシステムはany文字を含むファイル名を保存でき、無効な文字を含むファイル名を窒息させるのは、エンコーディングを考慮に入れるのはユーザープログラムだけであることを説明します。つまり、ファイルシステムとカーネルは、/
を含むファイル名を問題なく処理できます。
これも間違っていると思います。
エンコードはどこで行われ、特定の文字を許可しないという制限はどこにありますか?
短い答え:Unix/Linux/BSDカーネル、namei()
関数に課せられた制限。エンコードは、xterm
、firefox
、ls
などのユーザーレベルのプログラムで行われます。
あなたは間違った前提から始めていると思います。 Unixのファイル名は、任意の値を持つバイトの文字列です。いくつかの値、0x0(ASCII Nul)と0x2f(ASCII '/')は、マルチバイト文字エンコーディングの一部としてではなく、何でも許可されていません。 「バイト」には、文字を表す数値を含めることができます(ASCIIおよびその他のエンコーディング))が、「文字」には1バイト以上が必要になる場合があります(たとえば、UTF-で0x7fを超えるコードポイントUnicodeの8つの表現)。
これらの制限は、ファイル名の印刷規則とASCII文字セットです。元のUnixで使用されていたASCII '/'(数字で0x2f)の値のバイトで区切られています。部分的または完全に修飾されたパス( '/ usr/bin/cat'には "usr"、 "bin"、 "cat"の断片があります)使用された元のUnixはASCII Nul to terminate文字列。これらの2つの値以外のファイル名のバイトは、他の値をとることがあります。これのエコーは、UnicodeのUTF-8エンコーディングで確認できます。PrintableASCII文字を含む '/ '、UTF-8で1バイトのみを使用します。上記のコードポイントのUTF-8には、Nul制御文字を除いて、ゼロ値のバイトは含まれません。UTF-8は、Plan-9、The Prenender to the Throneのために発明されましたUnix。
古いUnix(およびLinuxのように見える)には、一度に1バイトずつパスを調べ、0x2F値のバイトでパスを分割し、ゼロ値のバイトで停止するnamei()
関数がありました。 namei()
はUnix/Linux/BSDカーネルの一部であるため、例外的なバイト値が適用されます。
ここまでは、文字ではなくバイト値について説明してきました。 namei()
は、バイトに文字セマンティクスを適用しません。これは、ls
のようなユーザーレベルのプログラム次第です。これは、バイト値または文字値に基づいてファイル名をソートする場合があります。 xterm
は、文字エンコードに基づいて、ファイル名に使用するピクセルを決定します。 xterm
を指定しないと、UTF-8でエンコードされたファイル名を持っているので、それを呼び出すと、意味不明なことが多く見られます。 vim
がUTF-8(または、UTF-16、UTF-32)エンコーディングを検出するようにコンパイルされていない場合、UTF-8を含む「テキストファイル」を開くと、意味不明なことが多く表示されます。エンコードされた文字。
バイトと文字の分離は、Unixが設計されてからかなりの時間を要しました。それが設計されたとき、単語の使用は8(または6、または9)ビットがどのように解釈されたかについて何かを伝えましたが、単語エンコーディングはそうではありませんでした言及した。
ファイル名はバイトのシーケンスです。 0x2f "/"以外のバイトは許可されます。文字列ターミネータとして使用されているため、0x00を含むバイトはカーネルに到達することさえできません。アプリケーションは、選択したエンコーディングに従ってバイトシーケンスを解釈できます。それが厄介に聞こえるなら、私はそれがそうだと思います。
詳細は http://www.gtk.org/api/2.6/glib/glib-Character-Set-Conversion.html をご覧ください。