12

如何创建一个实现OutputStream并将内容写入其中的类?

例如下面的打印方法是错误的,不会编译。有哪些选择或更好的技术?

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直接向其写入 a 。相反,您需要获取byte[]of String,然后将它们写出到流中。

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

有关支持的写入数据类型的更多信息,请参阅OutputStream java 文档。

我的建议是确保OutputStream您在构造函数中提供的是 a BufferedOutputStream,因为这将提高代码的性能。它的工作原理是缓冲内存中的一些数据,并将其以大块的形式写入磁盘,而不是许多较小的写入。

这是BufferedOutputStream的 java 文档

于 2012-06-04T02:21:51.657 回答
9

我认为其他答案缺少重要的一点/问题。

你真的应该使用 OutputStream 吗?

和类层次结构用于写入OutputStreamInputStream读取面向字节的数据。但是 Java 字符串不是面向字节的。它们是面向字符的(初步近似),Java 中的字符是 16 位 Unicode 代码单元。

当您将字符写入字节流时,JVM 必须进行转换以将字符编码为字节。事实上,有很多可能的方法可以做到这一点。例如,UTF-8 将序列中的每个字符编码为一个或多个字节,Latin-1 或 ASCII 将字符子集编码为单个字节,并将其他字符(可能)变成问号。等等。

现在,可以这样写:

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

但它有一个问题。问题是 a 上的getBytes()方法String使用 JVM 的默认字符编码方案进行转换。这(默认编码方案)取决于启动 JVM 的环境。因此,该代码根据环境执行不同的操作。现在您可以通过指定字符集来解决这个问题:

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

但是如果你在很多地方调用 getBytes 就会变得很麻烦。

如果您正在执行大量基于文本的输出,更好的主意是使用WriterAPI 而不是OutputStreamAPI。WriterAPI 及其实现在后台处理转换......并且更加一致和有效。

最后一点是,还有其他 API 可以帮助进行基于文本的输出。

  • 该类BufferedWriter(以及BufferedOutputStream)通过在输出过程中引入内存缓冲来支持高效输出。这可以节省系统调用,尤其是在您执行大量小型写入操作时。
  • 该类PrintWriter提供了很多方便的方法,并且还消除了处理 IOExceptions 的需要。(如果发生 IOException,则会PrintWriter记录下来。有一种方法可以测试是否发生了异常。这可能有用也可能很危险,具体取决于您在做什么......)
于 2012-06-04T03:15:51.483 回答
2

要写出字符串,请查看PrintStream该类。您可以在此处看到一个执行您想要的类的示例。

OutputStream此外,您可以使用以下PrintStream构造函数之一包装一个:

public class FooBarPrinter{
  private PrintStream p;
  public FooBarPrinter(OutputStream o){
    p = new PrintStream(o);
  }
  public void print(String s){      
    p.print(s);
  }
}

编辑:请注意,您也可以PrintWriter以与上述相同的方式使用该类PrintStream;这通常更好,因为您可以指定要使用的编码,避免任何平台依赖性。

于 2012-06-04T02:26:15.220 回答