文件编码是否影响基于纯字节层面的Java文件对比?
文件对比代码是否受编码影响?
我用下面这段代码对比两个理论上完全相同的文件(支持任意类型和大小)。我知道像TXT、HTML这类文本文件,编码会影响字节序列到字符的转换——同一字节序列用UTF-8和ASCII编码显示的内容不一样。想问问这段代码会不会受文件编码影响?毕竟我是在纯字节层面对比,没涉及字节转字符的操作。
bin_1 = new BufferedInputStream(file_input_stream_1); bin_2 = new BufferedInputStream(file_input_stream_2); byte[] barr_1 = new byte[8192]; byte[] barr_2 = new byte[8192]; while(bin_1.available() > 0){ bin_1.read(barr_1); bin_2.read(barr_2); if(Arrays.equals(barr_1, barr_2) == false){ break; } else{ barr_1 = new byte[8192]; barr_2 = new byte[8192]; continue; } }
结论:完全不受编码影响
你说的没错,这段代码是在纯字节层面做对比,和文件编码完全无关:
BufferedInputStream读取的是文件的原始字节数据,不会做任何编码转换,不管文件是文本还是二进制,都是原封不动读入字节数组。- 对比时用
Arrays.equals直接比对字节数组内容,全程没有“字节转字符”的步骤,编码规则根本没机会介入这个过程。
但要注意:这段代码本身有严重缺陷
available()方法不可靠:它返回的是当前流中可无阻塞读取的字节数,不是文件总大小。如果读取时出现阻塞(比如大文件、慢存储),循环会提前终止,导致对比不完整。- 忽略
read()的返回值:read(byte[])返回的是实际读取的字节数,不是数组长度。如果文件最后一段不足8192字节,数组未填充的部分会是默认的0,这时候Arrays.equals会误判为文件不同,哪怕实际内容完全一致。
正确的文件对比写法
import java.io.BufferedInputStream; import java.io.InputStream; import java.util.Arrays; public class FileComparator { public static boolean areFilesEqual(InputStream file_input_stream_1, InputStream file_input_stream_2) { try (BufferedInputStream bin1 = new BufferedInputStream(file_input_stream_1); BufferedInputStream bin2 = new BufferedInputStream(file_input_stream_2)) { byte[] barr1 = new byte[8192]; byte[] barr2 = new byte[8192]; int len1, len2; while ((len1 = bin1.read(barr1)) != -1) { len2 = bin2.read(barr2); // 先判断读取长度是否一致,再对比有效字节内容 if (len1 != len2 || !Arrays.equals(barr1, 0, len1, barr2, 0, len2)) { return false; } } // 检查第二个文件是否还有剩余内容(避免一个文件是另一个的前缀) return bin2.read() == -1; } catch (Exception e) { e.printStackTrace(); return false; } } }
内容的提问来源于stack exchange,提问作者william
相关产品推荐
相关产品推荐

