豊富なOutputStream
を使用してコンテンツを書き込むクラスを作成するにはどうすればよいですか?
たとえば、次の印刷方法は間違っており、コンパイルされません。オプションまたはより良いテクニックは何ですか?
public class FooBarPrinter{
private OutputStream o;
public FooBarPrinter(OutputStream o){
this.o=o;
}
public void print(String s){
o.write(s);
}
}
ジェネリックOutputStream
には、String
を直接書き込む機能はありません。代わりに、String
のbyte[]
を取得して、ストリームに書き込む必要があります。
public void print(String s){
o.write(s.getBytes());
}
サポートされている書き込みデータ型の詳細については、 OutputStream Javaのドキュメントを参照してください。
これを改善するための私の提案は、コンストラクタで提供するOutputStream
がBufferedOutputStream
であることを確認することです。これにより、コードのパフォーマンスが向上します。これは、データの一部をメモリにバッファリングし、多数の小さな書き込みではなく大きなチャンクでディスクに書き込むことによって機能します。
他の回答は重要な点・質問が欠けていると思います。
本当にOutputStreamを使用する必要がありますか?
OutputStream
およびInputStream
クラス階層は、バイト指向データの書き込みおよび読み取り用です。ただし、Java文字列はバイト指向ではありません。文字列(最初の概算では)であり、Javaの文字は16ビットUnicodeコード単位です。
文字をバイトストリームに書き込む場合、JVMは文字をバイトとしてencodeに変換する必要があります。実際、これを行うには多くの可能な方法があります。たとえば、UTF-8はシーケンス内の各文字を1つとしてエンコードしますまたはそれ以上バイト、Latin-1またはASCIIはサブセット)をエンコードします文字を1バイトとして、他の文字を(おそらく)疑問符に変換します。
今、このようなものを書くことが可能です:
_ public void print(String s){
o.write(s.getBytes());
}
_
しかし、問題があります。問題は、String
のgetBytes()
メソッドがJVMのデフォルトの文字エンコード方式を使用して変換を行うことです。そして、これ(デフォルトのコード化スキーム)は、JVMが起動された環境に依存します。したがって、そのコードは、環境に応じて異なる処理を行います。これで、文字セットを指定して修正できます。
_ public void print(String s){
o.write(s.getBytes("UTF-8"));
}
_
しかし、多くの場所でgetBytesを呼び出すと、面倒になります。
多くのテキストベースの出力を行う場合は、Writer
APIの代わりにOutputStream
APIを使用することをお勧めします。 Writer
APIとその実装は、内部での変換を処理します...より一貫して効率的に。
最後のポイントは、テキストベースの出力を行うのに役立つ他のAPIがあることです。
BufferedWriter
クラス(およびBufferedOutputStream
)は、出力プロセスにメモリ内バッファリングを導入することにより、効率的な出力をサポートします。これにより、特に小さな書き込み操作を多数実行している場合に、システムコールを節約できます。PrintWriter
クラスは、多くの便利なメソッドを提供し、IOExceptionsを処理する必要もなくなります。 (IOExceptionが発生した場合、PrintWriter
はそれを記録します。例外が発生したかどうかをテストする方法があります。これは、何をしているのかによって、有用または危険になる場合があります...)文字列を書き出すには、 PrintStream
クラスを見てください。意図したことを行うクラスの例 here を見ることができます。
また、 OutputStream
コンストラクターの1つ を使用してPrintStream
をラップできます。
public class FooBarPrinter{
private PrintStream p;
public FooBarPrinter(OutputStream o){
p = new PrintStream(o);
}
public void print(String s){
p.print(s);
}
}
[〜#〜] edit [〜#〜]: PrintWriter
も使用できることに注意してください上記のPrintStream
と同じ方法でクラスを作成します。これは通常、使用するエンコーディングを指定して、プラットフォームの依存関係を回避できるため、より優れています。