12

コンテンツを実装して書き込むクラスを作成するにはどうすればよいOutputStreamですか?

たとえば、次の print メソッドは間違っているため、コンパイルできません。オプションまたはより良いテクニックは何ですか?

public class FooBarPrinter{
    private OutputStream o;
    public FooBarPrinter(OutputStream o){
        this.o=o;
    }

    public void print(String s){        
        o.write(s);
    }
}
4

3 に答える 3

24

ジェネリックには、直接OutputStream書き込む機能がありません。String代わりに、byte[]のを取得Stringしてから、それらをストリームに書き出す必要があります。

public void print(String s){ 
    o.write(s.getBytes());
}

サポートされている書き込みデータ型の詳細については、 OutputStreamの Java ドキュメントを参照してください。

これを改善するための私の提案はOutputStream、コンストラクターで提供する が であることを確認することBufferedOutputStreamです。これにより、コードのパフォーマンスが向上します。データの一部をメモリにバッファリングし、多数の小さな書き込みではなく大きなチャンクでディスクに書き出すことで機能します。

BufferedOutputStreamの Java ドキュメントは次のとおりです。

于 2012-06-04T02:21:51.657 に答える
9

他の回答には重要な点/質問が欠けていると思います。

本当に OutputStream を使用する必要がありますか?

OutputStreamおよびInputStreamクラス階層は、バイト指向データの書き込みと読み取り用です。しかし、Java Strings はバイト指向ではありません。それらは文字指向であり (最初の概算)、Java の文字は 16 ビットの Unicode コード単位です。

文字をバイト ストリームに書き込む場合、JVM は文字をバイトとしてエンコードする変換を行う必要があります。実際、これを行うには多くの方法があります。たとえば、UTF-8 はシーケンス内の各文字を 1バイト以上としてエンコードし、Latin-1 または ASCII は文字のサブセットを 1 バイトとしてエンコードし、他の文字を (おそらく) 疑問符に変換します。等々。

これで、次のように書くことができます。

  public void print(String s){ 
      o.write(s.getBytes());
  }

しかし、それには問題があります。問題は、 のgetBytes()メソッドStringが JVM のデフォルトの文字エンコード方式を使用して変換を行うことです。そして、これ (デフォルトのエンコード方式) は、JVM が起動された環境に依存します。そのため、そのコードは環境に応じてさまざまなことを行います。これで、文字セットを指定して修正できます。

  public void print(String s){ 
      o.write(s.getBytes("UTF-8"));
  }

しかし、多くの場所で getBytes を呼び出している場合は面倒です。

テキストベースの出力が多い場合は、WriterAPI の代わりに APIを使用することをお勧めしOutputStreamます。API とそのWriter実装は、内部で変換を処理し、より一貫して効率的に処理します。

最後のポイントは、テキストベースの出力を行うのに役立つ API が他にもあるということです。

  • このBufferedWriterクラス (および もBufferedOutputStream) は、出力プロセスにインメモリ バッファリングを導入することにより、効率的な出力をサポートします。これにより、システム コールが節約されます。特に、小規模な書き込み操作を多数実行している場合はそうです。
  • このPrintWriterクラスは便利なメソッドを多数提供し、IOExceptions を処理する必要もありません。(IOException が発生した場合、PrintWriterはそれを記録します。例外が発生したかどうかをテストする方法があります。これは、何をしているかに応じて、有用または危険になる可能性があります ...)
于 2012-06-04T03:15:51.483 に答える
2

文字列を書き出すには、PrintStreamクラスを見てください。意図したとおりのクラスの例をここで見ることができます。

また、コンストラクターの 1 つをOutputStream使用してラップすることもできます。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これは通常、使用するエンコーディングを指定して、プラットフォームへの依存を回避できるため、優れています。

于 2012-06-04T02:26:15.220 に答える