アップロード テキスト ファイルを受信する Web サービスがあります。そのため、サーバー側でInputStreamオブジェクトを取得し、文字セットとして「UTF8」を使用してInputStreamReaderとしてラップしようとしました。しかし、US-ASCII でエンコードされたファイルをアップロードしても機能することに気付きました。Java は、ファイルを他のすべての文字セットから UTF8 に自動的に変換できるようです。私は正しいですか?charset 属性はどのように機能しますか?
5 に答える
UTF-8 は US-ASCII のスーパー セットです。
ASCII は 7 ビット文字 (0 から 127) であり、これらは US-ASCII と UTF-8 および他の多くの文字セットで変更されていません。ほとんどの文字セットが異なるのは上位ビット バイト (128 ~ 255) です。US-ASCII の場合は未定義です。ISO-8859-1 の場合、これらの文字は変更されず、255 文字まで許可されます。UTF-8 では、文字は次のようになります。 2 ~ 4 バイトを使用するようにエンコードされているため、最大 0x10FFFF または 128K 文字を表すことができます。
いいえ、Java は通常、ある文字セットを別の文字セットに自動的に変換しません。使用する文字セットを明示的に指定した場合は特にそうです。
ただし、UTF-8 は ASCII 互換です。つまり、すべての有効な ASCII ストリームは自動的に有効な UTF-8 ストリームにもなり、UTF-8 でエンコードされた ASCII 文字のみを含むテキストも有効な ASCII になります。
したがって、ASCII および UTF-8 入力のみを受け入れる場合は、すべてを UTF-8 として扱うことは完全に有効です。他のエンコーディングもサポートする予定がある場合は、実際に使用されているエンコーディングに関する情報も送信する何らかの方法が必要になります。
これは、US-ASCII が UTF-8 のサブセットであるためのみ機能します (すべての ASCII ファイルは、同じデータの有効な UTF-8 ファイルでもあります)。
他のもので試してみると、壊れます。
UTF-8 は ASCII と互換性があります。つまり、すべての ASCII ドキュメントも有効な UTF-8 です。ウィキペディアの引用:
[UTF-8] は、ASCII との下位互換性を確保し、UTF-16 と UTF-32 のエンディアンとバイト オーダー マークの複雑さを回避するために設計されました。
[...] ASCII と 1 対 1 で対応する Unicode の最初の 128 文字は、ASCII と同じバイナリ値を持つ単一のオクテットを使用してエンコードされ、有効な ASCII テキストを有効な UTF-8 エンコード Unicode にもします。
そのため、Java は引き続きストリームを UTF-8 として扱います。UTF-8 リーダーで UTF-16 または UTF-32 を使用しようとすると、ガベージが発生します。
なんで?ファイルをアップロードする場合は、InputStream を使用してください。ファイル データを UTF-16 に変換してから、場合によっては別のエンコーディングに戻すという面倒なことはしたくありません。
バイトをコピーするだけです。