Java如何比較兩個(gè)任意文件是否相同
一、比較規(guī)則
- 先比較兩個(gè)文件的長(zhǎng)度,如果不一樣則文件肯定不一樣。
- 否則將文件讀取出來(lái),一個(gè)字節(jié)一個(gè)字節(jié)的比較二者內(nèi)容是否相同。
public class FileCompare {
public static void main(String[] args) {
System.out.println("請(qǐng)依次輸入兩個(gè)文件的全路徑和文件名:");
System.out.println("firstFile:");
String firstFile = inputFileName();
System.out.println("secondFile:");
String secondFile = inputFileName();
System.out.println("Start to compare ...");
FileCompare fileCompare = new FileCompare();
fileCompare.compareFile(firstFile, secondFile);
}
private static String inputFileName() {
BufferedReader buffRead = new BufferedReader(new InputStreamReader(System.in));
String fileName = null;
try {
fileName = buffRead.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return fileName;
}
private void compareFile(String firFile, String secFile) {
try {
BufferedInputStream fir = new BufferedInputStream(new FileInputStream(firFile));
BufferedInputStream sec = new BufferedInputStream(new FileInputStream(secFile));
//比較文件的長(zhǎng)度是否一樣
if (fir.available() == sec.available()) {
while (true) {
int firRead = fir.read();
int secRead = sec.read();
if (firRead == -1 || secRead == -1) {
System.out.println("two files are same!");
break;
} else if (firRead != secRead) {
System.out.println("Files not same!");
break;
}
}
} else {
System.out.println("two files are different!");
}
fir.close();
sec.close();
return;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、File 中的 length() 與IO中 InputStream 類(lèi)中的 available()
1??File 中的 length() 返回 long,表示文件的大小。
2??IO 中 InputStream 類(lèi)中的 available() 返回 int。表示該 inputstream 在不被阻塞的情況下一次可以讀取到的數(shù)據(jù)長(zhǎng)度。
三、方法補(bǔ)充
除了上文的方法,小編還為大家整理了其他Java比較文件的方法,希望對(duì)大家有所幫助
java實(shí)現(xiàn)兩個(gè)文件對(duì)比
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class check {
public static void main(String[] args) {
Set<String> allStuNames = new HashSet<>();
try {
FileReader fileReader = new FileReader("name.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
// 逐行處理文本內(nèi)容
// System.out.println(line);
allStuNames.add(line);
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
// System.out.println(allStuNames);
List<String> lst = new ArrayList<>();
try {
FileReader fileReader = new FileReader("a.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader);
String line;
while ((line = bufferedReader.readLine()) != null) {
// 逐行處理文本內(nèi)容
// System.out.println(line);
lst.add(line);
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
for(String desc : lst){
for(String name : allStuNames){
if(desc.contains(name)){
System.out.println(name);
System.out.println(desc);
}
}
}
}
}利用md5判斷兩個(gè)文件是否相同
例子:
根據(jù)不同路徑下兩個(gè)文件來(lái)判斷:
package com.letv.test;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
public class CheckSameFile {
public static char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static void main(String[] args) {
String path1 = "d:/test/abc.jpg";
String path2 = "d:/test/asd/abc.jpg";
String hash_path1 = null;
String hash_path2 = null;
try {
hash_path1 = getHash(path1, "MD5");
hash_path2 = getHash(path2, "MD5");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("path1 md5:" + hash_path1);
System.out.println("path2 md5:" + hash_path2);
if (hash_path1.endsWith(hash_path2)) {
System.out.println("文件相同");
} else {
System.out.println("文件不相同");
}
}
/**
* 獲得文件md5值
*/
public static String getHash(String fileName, String hashType)
throws Exception {
InputStream fis;
fis = new FileInputStream(fileName);
byte[] buffer = new byte[1024];
MessageDigest md5 = MessageDigest.getInstance(hashType);
int numRead = 0;
while ((numRead = fis.read(buffer)) > 0) {
md5.update(buffer, 0, numRead);
}
fis.close();
return toHexString(md5.digest());
}
/**
* md5轉(zhuǎn)成字符串
*/
public static String toHexString(byte[] b) {
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; i++) {
sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
sb.append(hexChar[b[i] & 0x0f]);
}
return sb.toString();
}
}通過(guò)比較文件每一個(gè)字節(jié)判斷
public static boolean isSameFile(String filePath1, String filePath2) {
FileInputStream fis1 = null;
FileInputStream fis2 = null;
try {
fis1 = new FileInputStream(filePath1);
fis2 = new FileInputStream(filePath2);
// 獲取文件的總字節(jié)數(shù)
int len1 = fis1.available();
int len2 = fis2.available();
// 判斷兩個(gè)文件的字節(jié)長(zhǎng)度是否一樣,長(zhǎng)度相同則比較具體內(nèi)容
if (len1 == len2) {
// 建立字節(jié)緩沖區(qū)
byte[] data1 = new byte[len1];
byte[] data2 = new byte[len2];
// 將文件寫(xiě)入緩沖區(qū)
fis1.read(data1);
fis2.read(data2);
// 依次比較文件中的每個(gè)字節(jié)
for (int i = 0; i < len1; i++) {
if (data1[i] != data2[i]) {
System.out.println("文件內(nèi)容不一樣");
return false;
}
}
System.out.println("文件內(nèi)容相同");
return true;
} else {
// 文件長(zhǎng)度不一樣,內(nèi)容肯定不同
System.out.println("文件內(nèi)容不同");
return false;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
// 關(guān)閉資源
if (fis1!=null){
try {
fis1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis2!=null){
try {
fis2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
使用緩沖流比較,在比較大文件時(shí)效率相比普通流效率高
public static boolean isSameFile2(String filePath1, String filePath2) {
BufferedInputStream bis1 = null;
BufferedInputStream bis2 = null;
FileInputStream fis1 = null;
FileInputStream fis2 = null;
try {
// 獲取文件輸入流
fis1 = new FileInputStream(filePath1);
fis2 = new FileInputStream(filePath2);
// 將文件輸入流包裝成緩沖流
bis1 = new BufferedInputStream(fis1);
bis2 = new BufferedInputStream(fis2);
// 獲取文件字節(jié)總數(shù)
int len1 = bis1.available();
int len2 = bis2.available();
// 判斷兩個(gè)文件的字節(jié)長(zhǎng)度是否一樣,長(zhǎng)度相同則比較具體內(nèi)容
if (len1 == len2) {
// 建立字節(jié)緩沖區(qū)
byte[] data1 = new byte[len1];
byte[] data2 = new byte[len2];
// 將文件寫(xiě)入緩沖區(qū)
bis1.read(data1);
bis2.read(data2);
// 依次比較文件中的每個(gè)字節(jié)
for (int i = 0; i < len1; i++) {
if (data1[i] != data2[i]) {
System.out.println("文件內(nèi)容不一致");
return false;
}
}
System.out.println("文件內(nèi)容一致");
return true;
} else {
System.out.println("文件長(zhǎng)度不一致,內(nèi)容不一致");
return false;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis1 != null) {
try {
bis1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis2 != null) {
try {
bis2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis1 != null) {
try {
fis1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis2 != null) {
try {
fis2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
將文件分多次讀入,然后通過(guò)MessageDigest進(jìn)行MD5加密,最后再通過(guò)BigInteger類(lèi)提供的方法進(jìn)行16進(jìn)制的轉(zhuǎn)換
/**
* 計(jì)算文件的MD5值
*
* @param file
* @return
*/
public static String getFileMD5(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte[] buffer = new byte[8192];
int len;
try {
digest = MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer)) != -1) {
digest.update(buffer, 0, len);
}
BigInteger bigInt = new BigInteger(1, digest.digest());
return bigInt.toString(16);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
String filePath1="/Users/zhouzhxu/desktop/test.csv";
String filePath2="/Users/zhouzhxu/desktop/test2.csv";
String fileMD51 = getFileMD5(new File(filePath1));
String fileMD52 = getFileMD5(new File(filePath2));
System.out.println(fileMD51);
System.out.println(fileMD52);
}到此這篇關(guān)于Java如何比較兩個(gè)任意文件是否相同的文章就介紹到這了,更多相關(guān)Java比較文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring解決循環(huán)依賴問(wèn)題及三級(jí)緩存的作用
這篇文章主要介紹了Spring解決循環(huán)依賴問(wèn)題及三級(jí)緩存的作用,所謂的三級(jí)緩存只是三個(gè)可以當(dāng)作是全局變量的Map,Spring的源碼中大量使用了這種先將數(shù)據(jù)放入容器中等使用結(jié)束再銷(xiāo)毀的代碼風(fēng)格2022-07-07
java爬蟲(chóng)Gecco工具抓取新聞實(shí)例
本篇文章主要介紹了JAVA 爬蟲(chóng)Gecco工具抓取新聞實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-10-10
Java 數(shù)據(jù)庫(kù)連接池 DBCP 的介紹
這篇文章主要給大家分享的是 Java 數(shù)據(jù)庫(kù)連接池 DBCP 的介紹, 是 Apache 旗下 Commons 項(xiàng)目下的一個(gè)子項(xiàng)目,提供連接池功能DBCP,下面來(lái)看看文章的具體介紹內(nèi)容吧,需要的朋友可以參考一下2021-11-11
MyBatis注解開(kāi)發(fā)之實(shí)現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢
本文主要詳細(xì)介紹了MyBatis注解開(kāi)發(fā)中,實(shí)現(xiàn)自定義映射關(guān)系和關(guān)聯(lián)查詢,文中有詳細(xì)的代碼示例,對(duì)學(xué)習(xí)MyBatis有一定的參考價(jià)值,需要的朋友可以參考閱讀2023-04-04

