How to Cache InputStream for Multiple Use

后端 未结 10 1052
庸人自扰
庸人自扰 2020-11-29 05:57

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

POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream);
         


        
10条回答
  •  无人及你
    2020-11-29 06:28

    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();
        }
    }
    

    testcase

    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);
    }
    

    EDIT 2

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

提交回复
热议问题