30

この 2 つのクラスの違いがわかりません。いつ 1 つよりも 1 つを使用しますか? FileWriter が文字をファイルに出力できることは知っていますが、私が知る限り、OutputStreamWriter も同様です。ここに私がテストしたコードがいくつかあり、それらは同じように動作するようです。例外処理のものを追加していませんが、そこにあると仮定しましょう。

FileWriter writer = new FileWriter("C:\\Users\\owner\\Desktop\\demo.txt");
writer.write("hello");
writer.close();

私もこのコードを試しました:

File file = new File("C:\\Users\\owner\\Desktop\\demo.txt");
os = new OutputStreamWriter(new FileOutputStream(file));
os.write("hello");
os.close();

これらはどちらも私にとって同じように機能するようです。奇妙なことが起こるのは、write() メソッドに int 値を入れようとしたときだけです。FileWriter の例では、私の demo.txt は完全に空です。OutputStreamWriter の例では、テキスト ファイルにいくつかの奇妙なシンボルが表示されます。私はJavaの本を読んでいますが、OutputStreamWriterについて得た唯一の説明は、「文字のストリームをバイトのストリームに変換する」ということです.2番目の例では、テキストファイルにいくつかのバイトが表示されますか?

いくつかの説明をいただければ幸いです。

4

4 に答える 4

51

XXXInputStream と XXXOutputStream (XXX はさまざまで、多くのオプションがあります) は 8 ビット バイトを処理します。例えば、OutputStream.write(byte[] c);

XXXWriter または XXXReader は 16 ビット文字を扱います。たとえば、Reader.read(char[] cbuf).

OutputStreamWriter は、OutputStream をライターに変換します。ご想像のとおり、InputStreamReader は InputStream から Reader に変換します。逆のことをするクラス、つまり Reader を InputStream に変換するクラスを私は知りません。

FileWriter は、ファイルと対話するライターです。Java String は内部で char を使用するため (Unicode を処理できるように 16 ビット)、FileWriter は Unicode String で使用するための自然なクラスです。

FileOutputStream は、バイトをファイルに書き込むための OutputStream です。OutputStreams は文字 (または文字列) を受け入れません。これを OutputStreamWriter にラップすることで、String を受け入れる Writer が作成されます。

さて、本当の問題は、いつリーダー/ライターを使用し、いつストリームを使用するかということです。私は何年も Java を使用してきましたが、時々混乱することもあります。私は次のことが正しいと信じています。

便利なガイド - どちらを使用するかを決定する方法:

  1. バイナリ データ (画像など) を扱う場合は、Streams を使用します。
  2. 中国語などの非 ASCII Unicode 文字を使用している場合は、リーダー/ライターを使用します。
  3. 通常の ASCII テキスト (従来の 0 ~ 127 文字) を使用している場合は、(通常) どちらも使用できます。

その他のリンク:

Java IO の入力ストリームとリーダー

InputStream と InputStreamReader

于 2012-07-07T00:33:46.627 に答える
14

実際にはそれ自体に違いはなく、FileWriter単なる便利なクラスです。必要なもの自体を拡張OutputStreamWriterし、作成しますFileOutputStream

に関してwrite(int):そのメソッドは、指定されたコードポイントを持つ単一の文字をストリームに書き込みますが、数値のテキスト表現は書き込みません。

空のファイルに関しては、書き込んだものを基になるストアにフラッシュする場合は、常にバッファーをフラッシュする必要があることに注意してください (ファイルまたはネットワーク ストリームなど、考えられるものは何でも)。os.flush()書き込み後に呼び出すだけで、それで十分です。
編集: Thilo が正しく述べたように、ストリームを閉じると、既にストリーム (および基になるすべてのストリーム) がフラッシュされます。

最後になりましたが、ほとんどの場合、ライターに書き込む文字セット/エンコーディングを明示的に指定する必要があります。ライターは文字を書き込み、OutputStream はバイトを書き込むため、これらの文字をバイトにエンコードする方法を指定する必要があります。エンコーディングを指定しない場合は、システムのデフォルトが使用されますが、これは望ましくない場合があります。

于 2012-07-07T00:17:33.253 に答える
3

これはここから

java.io では、バイト IO または文字 IO のいずれかを行います。バイト IO は、そのデータが表すものを解釈することなく、あらゆる形式のデータに使用できます。Character IO は、文字のシーケンスとして表される情報を対象としています。

バイト IO の場合、例 1 の FileOutputStream のようなさまざまなタイプの InputStream/OutputStream クラスがあります。文字データの場合、例の FileWriter のようなさまざまな形式の Reader/Writer クラスがあります。バッファリングはどちらの場合でも実行できるため、BufferedWriter クラスと BufferedOutputStream クラスがあります。

文字 IO 文字を行うには、ある時点で何らかの形式のエンコーディングを使用してバイト データに変換する必要があります。FileWriter がそれを行います。そのため、ファイル名とともにエンコーディングを取得するコンストラクターがあります。一般的なエンコーディングには、UTF-8、UTF-16、および US-ASCII が含まれます。

OutputStreamWriter は、文字のエンコードのみを行うクラスです。そのため、これは Writer であり、そのコンストラクターは、オプションのエンコーディング パラメーターを持つパラメーターとして OutputStream を取ります。

明示的なエンコーディング仕様を省略すると、FileWriter と ByteArrayOutputStream の両方がプラットフォームのデフォルトのエンコーディングを使用します。これは JVM によって異なるため、非常に注意が必要です。

于 2012-07-07T00:21:16.527 に答える
2

エンコーディングを変更する場合は、FileOutputStream の代わりに OutputStreamWriter を使用します。FileOutputStream は、文字ファイルを書き込むための便利なクラスですデフォルトのエンコーディングを使用します。

次のようにエンコードを UTF-8 に強制します。

OutputStreamWriter osw = new OutputStreamWriter(
    new FileOutputStream(exportPath),
    Charset.forName("UTF-8").newEncoder() 
);
于 2012-08-06T13:27:53.997 に答える