Java12引入了一个新的方法 mismatch
,它属于java.nio.file.Files
类。此方法用于比较两个文件的内容,并返回第一个不匹配字节的位置。如果两个文件完全相同,则返回-1
。
Files.mismatch
方法声明
public static long mismatch(Path path1, Path path2) throws IOException
参数说明:
path1
: 第一个文件的路径。path2
: 第二个文件的路径。
返回值说明:
- 返回两个文件之间第一个不匹配字节的位置。如果两个文件完全相同,则返回
-1
。 - 如果一个文件是另一个文件的前缀,则返回较短文件的长度。
异常说明:
IOException
: 如果发生I/O错误,抛出IOException异常,例如文件不存在。
Files.mismatch
的使用
以下是一个使用Files.mismatch
方法的示例代码:
package com.morris.java12;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* 使用FileMismatch对文件进行比较
*/
public class FileMismatchDemo {
public static void main(String[] args) throws IOException {
FileWriter a1 = new FileWriter("d:/a1.txt");
a1.write("abc中国");
a1.write("efg");
a1.write("123");
a1.close();
FileWriter a2 = new FileWriter("d:/a2.txt");
a2.write("abc中国"); // 中文占3个字节
a2.write("efg");
a2.write("124");
a2.close();
long ap = Files.mismatch(Path.of("d:/a1.txt"), Path.of("d:/a2.txt"));
System.out.println("a1 and a2 mismatch: " + ap); // 14
FileWriter b1 = new FileWriter("d:/b1.txt");
b1.write("abc");
b1.close();
FileWriter b2 = new FileWriter("d:/b2.txt");
b2.write("abc");
b2.close();
long bp = Files.mismatch(Path.of("d:/b1.txt"), Path.of("d:/b2.txt"));
System.out.println("b1 and b2 mismatch: " + bp); // -1
}
}
运行结果如下:
a1 and a2 mismatch: 14
b1 and b2 mismatch: -1
如果文件内容相同,mismatch
方法将返回-1
。
如果文件内容不同,mismatch
方法将返回第一个不匹配字节的位置。
如果文件长度不同,如果一个文件是另一个文件的前缀,mismatch
方法将返回较短文件的长度。
这个新方法对文件比较非常有用,可以大大简化需要逐字节比较文件内容的代码。
Files.mismatch
的源码分析
public static long mismatch(Path path, Path path2) throws IOException {
if (isSameFile(path, path2)) {
return -1;
}
byte[] buffer1 = new byte[BUFFER_SIZE];
byte[] buffer2 = new byte[BUFFER_SIZE];
try (InputStream in1 = Files.newInputStream(path);
InputStream in2 = Files.newInputStream(path2)) {
long totalRead = 0;
while (true) {
int nRead1 = in1.readNBytes(buffer1, 0, BUFFER_SIZE);
int nRead2 = in2.readNBytes(buffer2, 0, BUFFER_SIZE);
int i = Arrays.mismatch(buffer1, 0, nRead1, buffer2, 0, nRead2);
if (i > -1) {
return totalRead + i;
}
if (nRead1 < BUFFER_SIZE) {
// we've reached the end of the files, but found no mismatch
return -1;
}
totalRead += nRead1;
}
}
}
底层使用了Arrays.mismatch()
比较两个文件的字节数组。