[英]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.