我尝试将InputStream复制到File,如果InputStream的大小大于1MB,则中止复制.在Java7中,我编写了如下代码:
public void copy(InputStream input, Path target) {
OutputStream out = Files.newOutputStream(target,
StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
boolean isExceed = false;
try {
long nread = 0L;
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = input.read(buf)) > 0) {
out.write(buf, 0, n);
nread += n;
if (nread > 1024 * 1024) {// Exceed 1 MB
isExceed = true;
break;
}
}
} catch (IOException ex) {
throw ex;
} finally {
out.close();
if (isExceed) {// Abort the copy
Files.deleteIfExists(target);
throw new IllegalArgumentException();
}
}}
Run Code Online (Sandbox Code Playgroud)
ByteArrayOutputStream然后得到size().但问题是InputStream可能没有markSupported(),因此InputStream不能在复制文件操作中重用.idr*_*sid 18
我个人的选择是一个InputStream包装器,它在读取字节时对字节进行计数:
public class LimitedSizeInputStream extends InputStream {
private final InputStream original;
private final long maxSize;
private long total;
public LimitedSizeInputStream(InputStream original, long maxSize) {
this.original = original;
this.maxSize = maxSize;
}
@Override
public int read() throws IOException {
int i = original.read();
if (i>=0) incrementCounter(1);
return i;
}
@Override
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
int i = original.read(b, off, len);
if (i>=0) incrementCounter(i);
return i;
}
private void incrementCounter(int size) throws IOException {
total += size;
if (total>maxSize) throw new IOException("InputStream exceeded maximum size in bytes.");
}
}
Run Code Online (Sandbox Code Playgroud)
我喜欢这种方法,因为它是透明的,它可以与所有输入流重复使用,并且可以很好地与其他库一起使用.例如,使用Apache Commons复制最大4KB的文件:
InputStream in = new LimitedSizeInputStream(new FileInputStream("from.txt"), 4096);
OutputStream out = new FileOutputStream("to.txt");
IOUtils.copy(in, out);
Run Code Online (Sandbox Code Playgroud)
PS:上面的实现与BoundedInputStream的主要区别在于BoundedInputStream在超出限制时不抛出异常(它只是关闭流)
有以下现成解决方案:
第一个问题:有没有更好的解决方案?
并不真地。当然,并没有明显好转。
第二个问题:我的另一个解决方案-在复制操作之前,我计算InputStream的大小。所以我将InputStream复制到ByteArrayOutputStream,然后获取size()。但问题是InputStream可能没有markSupported(),因此InputStream不能在复制文件操作中重用。
撇开以上是陈述而不是问题......
如果您已将字节复制到ByteArrayOutputStream,则可以ByteArrayInputStream从 所返回的字节数组创建一个baos.toByteArray()。所以你不需要标记/重置原始流。
然而,这是一种非常丑陋的实现方式。尤其是因为无论如何您都在读取和缓冲整个输入流。
| 归档时间: |
|
| 查看次数: |
6975 次 |
| 最近记录: |