当前位置: 首页 > 面试题库 >

如何缓存InputStream以便多次使用

韩智明
2023-03-14
问题内容

我有一个文件的InputStream,我使用apache poi组件像这样从中读取:

POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream);

问题是我需要多次使用同一流,并且POIFSFileSystem在使用后会关闭流。

缓存来自输入流的数据,然后将更多输入流提供给不同的POIFSFileSystem的最佳方法是什么?

编辑1:

高速缓存是指存储供以后使用,而不是用来加速应用程序。将输入流读入数组或字符串,然后为每次使用创建输入流是否更好?

编辑2:

抱歉,我再次提出问题,但是在桌面和Web应用程序中工作时,条件有些不同。首先,我从tomcat
Web应用程序中的org.apache.commons.fileupload.FileItem获得的InputStream不支持标记,因此无法重置。

其次,我希望能够将文件保留在内存中,以便在处理文件时更快地访问文件并减少io问题。


问题答案:

您可以使用以下版本来 修饰 传递给 POIFSFileSystem的 InputStream
,该版本在调用close()时会使用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



 类似资料:
  • 问题内容: 我需要能够重复使用多次,并且我认为以下代码可以工作,但只能在第一次使用。 码 请注意,ArrayTable是我的一类,它使用数组来提供用于处理表的接口。 题 在该程序中,调用该方法后立即将数据库直接显示给用户,因此任何涉及将初始读取保存到内存中的对象的解决方案都是无用的,因为那样就不会刷新数据(像浏览器一样思考) ;当您按“刷新”时,您希望它再次获取信息,而不仅仅是显示它第一次获取的信

  • 在我退出外壳后,我在容器中所做的一切都丢失了。有没有可能让它将自己的状态保存到图像定义的环境之外? 简单的测试:在一个Dockerfile中写从ubuntu然后创建图像: 使用:docker image ls获取图像,然后创建并运行容器: 进入后,触摸/选择/测试。然后退出shell。有什么魔法可以让容器完成后再次看到测试文件,而不必触摸其图像?还是说容器的目的就是永远不要保存其状态超过其图像?

  • 问题内容: 我已经在中解析了JSON数据,现在想使其脱机使用。有没有一种方法可以将JSON数据保存在电话上,以便在电话离线时可以查看数据? 有人知道一个例子吗? 编辑现在可以使用: 问题答案: 您有两种方法。您可以创建一个数据库,然后将所有数据保存在那里,并在需要时将其取回。或者,如果您拥有的数据不是很多,并且您不想处理数据库,那么您可以将json字符串写入存储卡中的文本文件,并在离线时稍后阅读。

  • 我在neo4j浏览器中运行不同类型的密码查询来检查我在neo4j图形数据库中的数据。这是一个离线分析工作,所以数据库是只读的(我可以写它,但不会有新的数据) 我想有一个"neo4j浏览器控制台会话"保存查询的结果,供以后使用,如: 因此,以后我可以运行多个查询(比前一个查询运行得更快),如 我该怎么做?我知道我可以使用“with”将它们放在一起,但第一个慢速查询将运行多次,我不希望这样。 目前我在

  • 本文向大家介绍如何临时存储数据以便以后在Oracle中使用?,包括了如何临时存储数据以便以后在Oracle中使用?的使用技巧和注意事项,需要的朋友参考一下 问题: 您要临时存储SQL的结果。 解 我们可以使用CREATE GLOBAL TEMPORARY TABLE语句创建一个表,该表临时存储会话的数据。此外,您可以指定是保留会话的临时表数据还是事务提交之前。我们可以进一步使用ON COMMIT

  • 问题内容: 我来自PHP背景,想知道是否可以用Python做到这一点。 在PHP中,您可以用一块石头杀死2只鸟,如下所示: 代替: 我可以做这个: 您检查是否存在,如果存在,则在一条语句中将其分配给变量。 我想知道是否可以用Python做到这一点?因此,不要这样做: 避免写两次。 问题答案: 可能不完全是您的想法,但是… 这个?