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 類中的 available()
1??File 中的 length() 返回 long,表示文件的大小。
2??IO 中 InputStream 類中的 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]; // 將文件寫入緩沖區(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]; // 將文件寫入緩沖區(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類提供的方法進(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é)束再銷毀的代碼風(fēng)格2022-07-07java爬蟲(chóng)Gecco工具抓取新聞實(shí)例
本篇文章主要介紹了JAVA 爬蟲(chóng)Gecco工具抓取新聞實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2016-10-10Java 數(shù)據(jù)庫(kù)連接池 DBCP 的介紹
這篇文章主要給大家分享的是 Java 數(shù)據(jù)庫(kù)連接池 DBCP 的介紹, 是 Apache 旗下 Commons 項(xiàng)目下的一個(gè)子項(xiàng)目,提供連接池功能DBCP,下面來(lái)看看文章的具體介紹內(nèi)容吧,需要的朋友可以參考一下2021-11-11MyBatis注解開(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