Azd*_*der 25 java caching inputstream apache-poi
我有一个文件的InputStream,我使用apache poi组件来读取它像这样:
POIFSFileSystem fileSystem = new POIFSFileSystem(inputStream);
Run Code Online (Sandbox Code Playgroud)
问题是我需要多次使用相同的流,POIFSFileSystem在使用后关闭流.
从输入流缓存数据然后将更多输入流提供给不同的POIFSFileSystem的最佳方法是什么?
编辑1:
通过缓存我的意思是存储供以后使用,而不是作为加速应用程序的方法.最好是将输入流读入数组或字符串,然后为每次使用创建输入流?
编辑2:
很抱歉重新打开这个问题,但在桌面和Web应用程序中工作时条件有所不同.首先,我从tomcat web app中的org.apache.commons.fileupload.FileItem获取的InputStream不支持标记,因此无法重置.
其次,我希望能够将文件保存在内存中,以便在处理文件时更快地访问和减少io问题.
Tom*_*asz 20
尝试BufferedInputStream,它将标记和重置功能添加到另一个输入流,并覆盖其close方法:
public class UnclosableBufferedInputStream extends BufferedInputStream {
public UnclosableBufferedInputStream(InputStream in) {
super(in);
super.mark(Integer.MAX_VALUE);
}
@Override
public void close() throws IOException {
super.reset();
}
}
Run Code Online (Sandbox Code Playgroud)
所以:
UnclosableBufferedInputStream bis = new UnclosableBufferedInputStream (inputStream);
Run Code Online (Sandbox Code Playgroud)
并使用bis之前使用过inputStream的地方.
dfa*_*dfa 18
您可以使用一个版本来装饰传递给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();
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
你可以用byte [](slurp模式)读取整个文件,然后将它传递给ByteArrayInputStream
小智 5
这可以正常工作:
byte[] bytes = getBytes(inputStream);
POIFSFileSystem fileSystem = new POIFSFileSystem(new ByteArrayInputStream(bytes));
Run Code Online (Sandbox Code Playgroud)
getBytes是这样的:
private static byte[] getBytes(InputStream is) throws IOException {
byte[] buffer = new byte[8192];
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
int n;
baos.reset();
while ((n = is.read(buffer, 0, buffer.length)) != -1) {
baos.write(buffer, 0, n);
}
return baos.toByteArray();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
38999 次 |
| 最近记录: |