如何缓存InputStream中多次使用 [英] How to Cache InputStream for Multiple Use

查看:1075
本文介绍了如何缓存InputStream中多次使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文件的InputStream和我使用Apache POI组件来读这样的:

I have an InputStream of a file and i use apache poi components to read from it like this:

POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream);

的问题是,我需要使用相同的流多次和POIFSFileSystem使用后关闭该流

The problem is that i need to use the same stream multiple times and the POIFSFileSystem closes the stream after use.

这是对从输入流缓存的数据,然后为更多输入的最佳方式流至不同POIFSFileSystem

What is the best way to cache the data from the input stream and then serve more input streams to different POIFSFileSystem ?

编辑1:

通过缓存我的意思店以备后用,而不是作为一种用来加快应用程序。也就是它更好地只是读了输入流到一个数组或字符串,然后创建输入流,每次使用?

By cache i meant store for later use, not as a way to speedup the application. Also is it better to just read up the input stream into an array or string and then create input streams for each use ?

编辑2:

对不起,重新讨论这个问题,但里面的桌面和Web应用程序时的条件有所不同。
首先,InputStream的我从org.apache.commons.fileupload.FileItem的得到我的Tomcat Web应用程序不支持的标记因此无法复位。

Sorry to reopen the question, but the conditions are somewhat different when working inside desktop and web application. First of all, the InputStream i get from the org.apache.commons.fileupload.FileItem in my tomcat web app doesn't support markings thus cannot reset.

第二,我希望能够与文件打交道时保持文件在内存中存取权限更快和更少的IO问题。

Second, I'd like to be able to keep the file in memory for faster acces and less io problems when dealing with files.

推荐答案

您可以装饰的InputStream传递给的 POIFSFileSystem 的一个版本是,当接近()被调用它具有复位()回应:

you can decorate InputStream being passed to POIFSFileSystem with a version that when close() is called it respond with reset():

class ResetOnCloseInputStream extends InputStream {

    private final InputStream decorated;

    public ResetOnCloseInputStream(InputStream anInputStream) {
        if (!anInputStream.markSupported()) {
            throw new IllegalArgumentException("marking not supported");
        }

        anInputStream.mark( 1 << 24); // magic constant: BEWARE
        decorated = anInputStream;
    }

    @Override
    public void close() throws IOException {
        decorated.reset();
    }

    @Override
    public int read() throws IOException {
        return decorated.read();
    }
}

测试用例

static void closeAfterInputStreamIsConsumed(InputStream is)
        throws IOException {
    int r;

    while ((r = is.read()) != -1) {
        System.out.println(r);
    }

    is.close();
    System.out.println("=========");

}

public static void main(String[] args) throws IOException {
    InputStream is = new ByteArrayInputStream("sample".getBytes());
    ResetOnCloseInputStream decoratedIs = new ResetOnCloseInputStream(is);
    closeAfterInputStreamIsConsumed(decoratedIs);
    closeAfterInputStreamIsConsumed(decoratedIs);
    closeAfterInputStreamIsConsumed(is);
}

编辑2

您可以读取一个byte [](啜食模式)的全部文件,然后将它传递给一个ByteArrayInputStream

EDIT 2

you can read the entire file in a byte[] (slurp mode) then passing it to a ByteArrayInputStream

这篇关于如何缓存InputStream中多次使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆