【问题标题】:How to convert Reader to InputStream in java如何在Java中将Reader转换为InputStream
【发布时间】:2021-04-08 23:23:01
【问题描述】:

我需要将 Reader 对象转换为 InputStream。我现在的解决方案如下。但我担心的是,由于这将处理大量数据,因此会大大增加内存使用量。

private static InputStream getInputStream(final Reader reader) {
   char[] buffer = new char[10240];
   StringBuilder builder = new StringBuilder();
   int charCount;
   try {
      while ((charCount = reader.read(buffer, 0, buffer.length)) != -1) {
         builder.append(buffer, 0, charCount);
      }
      reader.close();
   } catch (final IOException e) {
      e.printStackTrace();
   }
   return new ByteArrayInputStream(builder.toString().getBytes(StandardCharsets.UTF_8));
}

由于我使用 StringBuilder,这会将阅读器对象的全部内容保存在内存中。我想避免这种情况。有没有办法可以管道阅读器对象?对此高度赞赏的任何帮助。

【问题讨论】:

  • 您究竟需要InputStream 做什么?如果您想将数据写入某个地方,也许不需要中间InputStream
  • 获取输出流而不是输入流通常更容易。

标签: java memory-management inputstream reader


【解决方案1】:

使用 Apache Commons IO 库,您可以在一行中完成此转换:

//import org.apache.commons.io.input.ReaderInputStream;

    
    InputStream inputStream = new ReaderInputStream(reader, StandardCharsets.UTF_8);

您可以在https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/input/ReaderInputStream.html阅读本课程的文档

可能值得尝试一下,看看它是否也解决了内存问题。

【讨论】:

  • 我从没想过 Apache 也涵盖了这种用法。本来可以为我省力的。
  • 非常感谢您的回复。这对我来说非常有用。很高兴知道 commons.io 对此有内置功能。
【解决方案2】:

首先:一个罕见的需求,通常是相反的,或者有一个FileChannel,所以可以使用一个ByteBuffer。

一个 PipedInputStream 是可能的,在第二个线程中启动一个 PipedOutputStream。然而,这是不必要的。

阅读器给出字符。 Unicode 代码点来自一个或两个字符(后者是代理对)。

/**
 * Reader for an InputSteam of UTF-8 text bytes.
 */
public class ReaderInputStream extends InputStream {

    private final Reader reader;
    private boolean eof;
    private int byteCount;
    private byte[] bytes = new byte[6];

    public ReaderInputStream(Reader reader) {
        this.reader = reader;
    }
    
    @Override
    public int read() throws IOException {
        if (byteCount > 0) {
            int c = bytes[0];
            --byteCount;
            for (int i = 0; i < byteCount; ++i) {
                bytes[i] = bytes[i + 1];
            }
            return c;
        }
        if (eof) {
            return -1;
        }

        int c = reader.read();
        if (c == -1) {
            eof = true;
            return -1;
        }
        char ch = (char) c;
        String s;
        if (Character.isHighSurrogate(ch)) {
            c = reader.read();
            if (c == -1) {
                // Error, low surrogate expected.
                eof = true;
                //return -1;
                throw new IOException("Expected a low surrogate char i.o. EOF");
            }
            char ch2 = (char) c;
            if (!Character.isLowSurrogate(ch2)) {
                throw new IOException("Expected a low surrogate char");
            }
            s = new String(new char [] {ch, ch2});
        } else {
            s = Character.toString(ch);
        }
        byte[] bs = s.getBytes(StandardCharsets.UTF_8);
        byteCount = bs.length;
        System.arraycopy(bs, 0, bytes, 0, byteCount);
        return read();
    }
}

        Path source = Paths.get("...");
        Path target = Paths.get("...");
        try (Reader reader = Files.newBufferedReader(source, StandardCharsets.UTF_8);
                InputStream in = new ReaderInputStream(reader)) {
            Files.copy(in, target);
        }

【讨论】:

    猜你喜欢
    • 2020-08-13
    • 2010-09-08
    • 2019-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2011-09-21
    • 1970-01-01
    相关资源
    最近更新 更多