7

我有一个函数,int readFully(FileHandle handle, OutputStream out)它从 SSH 服务器读取整个文件并将其存储在本地流中。我可以使用 aFileOutputStream作为第二个参数在本地写入文件,然后BufferedImage使用类似这样的方法将该文件读入 a:

bufferedImage = ImageIO.read(new File("/path/to/file"));

但是如何在不先将其写入文件的情况下直接创建 bufferedImage 呢?我看了这个问题,但仍然无法解决我的情况。

4

3 回答 3

13

只需写入 a ByteArrayOutputStream- 然后您可以创建 aByteArrayInputStream以从同一字节数组中读取,然后将其传递给ImageIO.read(InputStream).

ByteArrayOutputStream output = new ByteArrayOutputStream();
readFully(handle, output);
byte[] data = output.toByteArray();
ByteArrayInputStream input = new ByteArrayInputStream(data);
BufferedImage image = ImageIO.read(input);

那是假设您实际上InputStream不能直接从 中创建一个FileHandle,这会更简单。

于 2013-07-03T15:34:41.873 回答
3

你可以像这样使用 aPipedInputStream和 a PipedOutputStream

PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);

readFully(handle, pos);

ImageIO.read(pis);

管道输出/输入流是链接的,因此“写入”的pos内容可以从pis.

编辑

乔恩指出,文件指出

不建议尝试从单个线程中使用这两个对象,因为它可能会使线程死锁。

你不应该在同一个线程中使用它。如果你想要一个单线程代码,你可以使用 ByteArrayOutputStream / ByteArrayInputStream:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
readFully(handle, baos);

ImageIO.read(new ByteArrayInputStream(baos.toByteArray());

从 JDK 1.0 开始,所有这些类(PipedInputStreamPipedOutputStreamByteArrayInputStreamByteArrayOutputStream)都存在。

于 2013-07-03T15:37:43.867 回答
0

因为管道 I/O 是一个好主意,但有一个线程问题,以下来自 @ssssteffff 的盗窃。

    try {
        final PipedOutputStream out = new PipedOutputStream();
        PipedInputStream in = new PipedInputStream(out);

        new Thread(){

            @Override
            public void run() {
                try {
                    readFully(handle, out);
                    out.close();
                } catch (IOException ex) {
                    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        }.start();

        BufferedImage img = ImageIO.read(in);
        in.close();

        ...            
    } catch (IOException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
  • out在一个新的线程中。
  • 管道输入in连接到输出,等待其数据。
  • 在 Java 8 中可能更受欢迎。
于 2013-07-03T16:00:06.343 回答