我需要實現相同的邏輯:比較文件使用InputStream
進行比較的二進制形式,和Reader
比較unicode。 我可以不知何故做一個方法,採取InputStream
或Reader
並採取相同的邏輯read()
採取參數的方法。InputStream或Reader。具有相同邏輯的方法
找不到通配符,因爲我看到InputStream
和Reader
沒有交互層次結構。
我需要一個方法,需要BufferedInputStream
或BufferedReader
。
我需要實現相同的邏輯:比較文件使用InputStream
進行比較的二進制形式,和Reader
比較unicode。 我可以不知何故做一個方法,採取InputStream
或Reader
並採取相同的邏輯read()
採取參數的方法。InputStream或Reader。具有相同邏輯的方法
找不到通配符,因爲我看到InputStream
和Reader
沒有交互層次結構。
我需要一個方法,需要BufferedInputStream
或BufferedReader
。
您可以使用重載創建兩個方法來表示每個方法都需要您想要支持的輸入之一。
定義一個接口,其中包含您需要從兩個方法訪問的功能,然後編寫實現該接口的包裝類(這些可以是相應方法中的匿名內部類)。
將包裝後的輸入傳遞給一個在接口上工作的內部私有處理方法,並且不關心它可能包裝什麼。
只需爲每個對象添加一個新的方法和一個新的包裝器,就可以擴展它來支持任意數量的不同類型的傳入對象(只要它們可以包裝它們)。
一些或多或少的通用方法,您可以根據自己的需求進行擴展。這個想法是將原始流傳輸到另一個流,以便在當前線程中讀取原始流時由另一個線程讀取。所以TeeInputStream
這裏用於包裝原始流並將數據流的副本發送到PipeOutputStream
。 PipeOutputStream
正在被PipeInputStream
讀取,即在單獨的線程中運行。當兩個數據流被完全讀取時,數據流的內容由MD5「散列」以進行比較,但是您可以使用任何想要比較字節數據(比較等)的方法。
這有點冗長,但如果您需要將流供給到XML閱讀器並同時計算流的CRC或MD5校驗和而不從流讀取兩次,則工作良好。
import org.apache.commons.io.input.TeeInputStream;
import java.io.*;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Test1 {
private static final ExecutorService executor = Executors.newFixedThreadPool(2);
public static boolean compareStreams(InputStream is1, InputStream is2) throws Exception {
// create pipe that will copy data from is1 to pipe accessible by pis1
final PipedOutputStream pos1 = new PipedOutputStream();
final PipedInputStream pis1 = new PipedInputStream(pos1, 1024);
final TeeInputStream tee1 = new TeeInputStream(is1, pos1, true);
// create pipe that will copy data from is2 to pipe accessible by pis2
final PipedOutputStream pos2 = new PipedOutputStream();
final PipedInputStream pis2 = new PipedInputStream(pos2, 1024);
final TeeInputStream tee2 = new TeeInputStream(is2, pos2, true);
class Comparator implements Runnable {
private final InputStream is;
final MessageDigest md = MessageDigest.getInstance("MD5");
public Comparator(InputStream is) throws Exception {
this.is = is;
}
@Override
public void run() {
byte[] arr = new byte[1024];
int read = 0;
try {
while ((read = is.read(arr)) >= 0) {
md.update(arr, 0, read);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Comparator comparatorIs1 = new Comparator(pis1);
Future<?> f1 = executor.submit(comparatorIs1);
Comparator comparatorIs2 = new Comparator(pis2);
Future<?> f2 = executor.submit(comparatorIs2);
Reader r1 = new InputStreamReader(is1);
Reader r2 = new InputStreamReader(is2);
char[] c1 = new char[1024];
char[] c2 = new char[1024];
int read1 = 0;
int read2 = 0;
boolean supposeEquals = true;
while (supposeEquals) {
read1 = r1.read(c1);
read2 = r2.read(c2);
if (read1 != read2 || (read1 < 0 && read2 < 0)) {
break;
}
for (int i = 0; i < read1; i++) {
if (c1[i] != c2[i]) {
supposeEquals = false;
break;
}
}
}
f1.cancel(true);
f2.cancel(true);
return read1 == read2 && supposeEquals && Arrays.equals(comparatorIs1.md.digest(), comparatorIs2.md.digest());
}
public static void main(String[] args) throws Exception {
System.out.println("Comparison result : " + compareStreams(new ByteArrayInputStream("test string here".getBytes()), new ByteArrayInputStream("test string here".getBytes())));
System.out.println("Comparison result : " + compareStreams(new ByteArrayInputStream("test string test".getBytes()), new ByteArrayInputStream("test string here".getBytes())));
System.out.println("Comparison result : " + compareStreams(new ByteArrayInputStream("test".getBytes()), new ByteArrayInputStream("test string here".getBytes())));
}
}
你還需要一些共同的字符和字節... – wero
這兩種情況下的邏輯實際上是否相同?你在比較什麼? –