【问题标题】:Efficient way to write InputStream to a File in Java 6在 Java 6 中将 InputStream 写入文件的有效方法
【发布时间】:2014-05-05 00:38:38
【问题描述】:

我将从第三方库获取输入流到我的应用程序。 我必须将此输入流写入文件。

下面是我试过的代码sn-p:

private void writeDataToFile(Stub stub) { 
    OutputStream os = null;
    InputStream inputStream = null;

    try {

        inputStream = stub.getStream();
        os = new FileOutputStream("test.txt");
        int read = 0;
        byte[] bytes = new byte[1024];

        while ((read = inputStream.read(bytes)) != -1) {
            os.write(bytes, 0, read);
        }

    } catch (Exception e) {

        log("Error while fetching data", e);

    } finally {
        if(inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                log("Error while closing input stream", e);
            }
        }
        if(os != null) {
            try {
                os.close();
            } catch (IOException e) {
                log("Error while closing output stream", e);
            }
        }
    }
 }

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: java inputstream


    【解决方案1】:

    既然您被 Java 6 所困,请帮自己一个忙,使用 Guava 及其 Closer

    final Closer closer = Closer.create();
    final InputStream in;
    final OutputStream out;
    final byte[] buf = new byte[32768]; // 32k
    int bytesRead;
    
    try {
        in = closer.register(createInputStreamHere());
        out = closer.register(new FileOutputStream(...));
        while ((bytesRead = in.read(buf)) != -1)
            out.write(buf, 0, bytesRead);
        out.flush();
    } finally {
        closer.close();
    }
    

    如果您使用 Java 7,解决方案会很简单:

    final Path destination = Paths.get("pathToYourFile");
    try (
        final InputStream in = createInputStreamHere();
    ) {
        Files.copy(in, destination);
    }
    

    yourInputStream 将作为“奖励”为您自动关闭; Files 会自己处理 destination

    【讨论】:

    • 文件和路径是 Java 7 的概念。但我的应用程序使用 Java 6 运行。Java 6 中是否有类似上述的解决方案。
    • 哎呀。好的,那你可以使用外部库吗?我在考虑这里的番石榴
    • 仅供参考,Files 库在 Android 的 Java 1.7 中不可用。被这个刺痛了。 stackoverflow.com/questions/24869323/…
    • java 7 的答案不正确,至少是 guava 18 版
    • @JoshPinter 是的,你一定想知道为什么。这个 API 比 File 好多了,没有可比性。
    【解决方案2】:

    如果您不在 Java 7 上并且无法使用 fge 的解决方案,您可能希望将 OutputStream 包装在 BufferedOutputStream 中

    BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream("xx.txt"));
    

    这种缓冲的输出流会将字节以块的形式写入文件,这比逐字节写入效率更高。

    【讨论】:

      【解决方案3】:

      使用 OutputStreamWriter 可以变得更干净:

      OutputStream outputStream = new FileOutputStream("output.txt");
      Writer writer = new OutputStreamWriter(outputStream);
      
      writer.write("data");
      
      writer.close();
      

      您可以在 inputStream 上使用 Scanner,而不是编写字符串

      Scanner sc = new Scanner(inputStream);
      while (sc.HasNext())
          //read using scanner methods
      

      【讨论】:

      • 虽然 OP 提到了 .txt 文件,但此解决方案有两个主要不便之处: 1. Scanner 将取消分隔符; 2.Writer中没有指定编码。因此,您将删除换行符(因为这是Scanner 的默认分隔符)并且您可能不使用正确的编码,因为您收到的是字节,而不是字符。关于后一个问题的更多细节here.
      猜你喜欢
      • 2016-03-19
      • 2011-06-06
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 2012-08-06
      • 2016-12-22
      • 1970-01-01
      • 2018-11-05
      相关资源
      最近更新 更多