[英]Inline input stream processing in Java
我需要一些关于以下问题的帮助。 我正在做一个需要处理文件的项目。 我从用户那里获得输入流的句柄,在将其写入磁盘之前,我需要执行某些步骤。
如果在我尝试使用管道输出和输入流的过程中出现任何异常,还需要中断流程,但约束是 Java 建议它在 2 个单独的线程中运行。 一旦我从输入流中读取,我就无法在其他处理步骤中使用它。 文件可能非常大,因此无法缓存缓冲区中的所有数据。 请提供您的建议,或者我可以使用任何第三方库。
最大的问题是您需要提前查看提供的 InputStream 以确定您是否收到了 zipfile。
private boolean isZipped(InputStream is) throws IOException {
try {
return new ZipInputStream(is).getNextEntry() != null;
} catch (final ZipException ze) {
return false;
}
}
在此之后,您需要在设置 DigestInputStream 之前将输入流重置为初始位置。 然后直接读取 ZipInputstream 或 DigestInputstream。 完成处理后,将 DigestInputStream 读到最后,以便获得摘要。 下面的代码已通过包装“CountingInputstream”进行验证,该包装跟踪从提供的 FileInputStream 读取的总字节数。
final FileInputStream fis = new FileInputStream(filename);
final CountingInputStream countIs = new CountingInputStream(fis);
final boolean isZipped = isZipped(countIs);
// make sure we reset the inputstream before calculating the digest
fis.getChannel().position(0);
final DigestInputStream dis = new DigestInputStream(countIs, MessageDigest.getInstance("SHA-256"));
// decide which inputStream to use
InputStream is = null;
ZipInputStream zis = null;
if (isZipped) {
zis = new ZipInputStream(dis);
zis.getNextEntry();
is = zis;
} else {
is = dis;
}
final File tmpFile = File.createTempFile("Encrypted_", ".tmp");
final OutputStream os = new CipherOutputStream(new FileOutputStream(tmpFile), obtainCipher());
try {
readValidateAndWriteRecords(is, os);
failIf2ndZipEntryExists(zis);
} catch (final Exception e) {
os.close();
tmpFile.delete();
throw e;
}
System.out.println("Digest: " + obtainDigest(dis));
dis.close();
System.out.println("\nValidating bytes read and calculated digest");
final DigestInputStream dis2 = new DigestInputStream(new CountingInputStream(new FileInputStream(filename)), MessageDigest.getInstance("SHA-256"));
System.out.println("Digest: " + obtainDigest(dis2));
dis2.close();
不是很相关,但这些是辅助方法:
private String obtainDigest(DigestInputStream dis) throws IOException {
final byte[] buff = new byte[1024];
while (dis.read(buff) > 0) {
dis.read(buff);
}
return DatatypeConverter.printBase64Binary(dis.getMessageDigest().digest());
}
private void readValidateAndWriteRecords(InputStream is, final OutputStream os) throws IOException {
final BufferedReader br = new BufferedReader(new InputStreamReader(is));
// do2unix is done automatically by readline
for (String line = br.readLine(); line != null; line = br.readLine()) {
// record length validation
if (line.length() < 1) {
throw new RuntimeException("RecordLengthValidationFailed");
}
os.write((line + "\n").getBytes());
}
}
private void failIf2ndZipEntryExists(ZipInputStream zis) throws IOException {
if (zis != null && zis.getNextEntry() != null) {
throw new RuntimeException("Zip File contains multiple entries");
}
}
==> 输出:
摘要: jIisvDleAttKiPkyU/hDvbzzottAMn6n7inh4RKxPOc=
CountingInputStream 关闭。 读取的总字节数:1100验证字节读取和计算摘要
摘要: jIisvDleAttKiPkyU/hDvbzzottAMn6n7inh4RKxPOc=
CountingInputStream 关闭。 读取的总字节数:1072
有趣的问题,我的回答可能太过分了:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.