Comparison of md5

As we all know, you can use md5 to compare whether two files are the same. When I wrote the demo, an error occurred. I used two methods to compare two files. Method 2 was more successful, but method 1 failed.
Note: test is the original video file, and test2 is the file that has been divided into blocks and then merged. Both can be played normally, with the same data size.

//方法1     失败
    String s1 = DigestUtils.md5Hex("E:\\test.mp4");
        String s2 = DigestUtils.md5Hex("E:\\test2.mp4");

        if (s2.equals(s1)){
            System.out.println("文件校验完整");
        }

  //方法2 成功
  FileInputStream fileInputStream_merge = new FileInputStream(mergeFile);
        FileInputStream fileInputStream_source = new FileInputStream(sourceFile);
        String s1 = DigestUtils.md5Hex(fileInputStream_merge);
        String s2 = DigestUtils.md5Hex(fileInputStream_source);

        if (s2.equals(s1)){
            System.out.println("文件校验完整");
        }

After searching for information,
the first way is to calculate the MD5 values ​​of the two copies, but the MD5 values ​​of the two copies are different, then it may be because the metadata of the two copies are different. Metadata includes information such as file creation time, modification time, and access time . If the information is different, the calculated MD5 value will also be different.
The second method calculates the MD5 value of two copies, and the MD5 values ​​of the two copies are the same, then it may be because the metadata of the two copies is the same, or only the metadata is different, but the file content is the same. Because the second way only counts the content of the file, regardless of the difference in metadata.
Summary: Comparing whether the files are consistent or not is generally to compare the content. Try to use streams to operate. Although stream operations are slow in io, they occupy less memory, and the method of directly reading files is the opposite.

   //测试分块
    @Test
    public void testChunk() throws IOException {
        //源文件
        File sourceFile = new File("E:\\test.mp4");
        //分块文件存储输出路径
        String chunkFilePath="E:\\chunck\\";
        //分块大小
        int chunkSize=1024*1024*1;
        //对块数向上取整
        int chunkNum= (int) Math.ceil(sourceFile.length()*1.0/chunkSize);
        //使用流从源文件读取数据
        RandomAccessFile r = new RandomAccessFile(sourceFile, "r");
        //缓存区
        byte [] bytes=new byte[1024];
        //循环写入文件
        for (int i = 0; i < chunkNum; i++) {
            //创建一个目标文件
            File file = new File(chunkFilePath + i);
            //从流中写到file
            RandomAccessFile rw = new RandomAccessFile(file, "rw");
            int len=-1;
            while ((len=r.read(bytes))!=-1){
                rw.write(bytes,0,len);
                if (file.length()>=chunkSize) break;
            }
            rw.close();
        }
        r.close();
    }

    //测试合并
    @Test
    public void testMerge() throws IOException {
        //块文件目录
        File chunkFile = new File("E:\\chunck\\");
        //源文件,用于比较md5值判断他们是否完整
        File sourceFile = new File("E:\\test.mp4");
        //合并后的文件
        File mergeFile = new File("E:\\test2.mp4");

        //取出所有分块文件
        File[] files = chunkFile.listFiles();
        //将数组转成list
        List<File> fileList = Arrays.asList(files);
        //对分块文件进行排序
        Collections.sort(fileList, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                return Integer.parseInt(o1.getName())-Integer.parseInt(o2.getName());
            }
        });
        //向合并文件写流
        RandomAccessFile rw = new RandomAccessFile(mergeFile, "rw");
        //缓存区
        byte[] bytes = new byte[1024];
        //遍历分块文件,向合并的文件写
        for (File file : fileList) {
            //读取分块的流
            RandomAccessFile r = new RandomAccessFile(file, "r");
            int len=-1;
            while ((len=r.read(bytes))!=-1){
                rw.write(bytes,0,len);
            }
            r.close();
        }
        rw.close();
        //合并文件完成后对文件进行md5校验
//        FileInputStream fileInputStream = new FileInputStream(mergeFile);
//        String s1 = DigestUtils.md5Hex("E:\\test.mp4");
//        String s2 = DigestUtils.md5Hex("E:\\test2.mp4");
        FileInputStream fileInputStream_merge = new FileInputStream("E:\\test.mp4");
        FileInputStream fileInputStream_source = new FileInputStream("E:\\test2.mp4");
        String s1 = DigestUtils.md5Hex(fileInputStream_merge);
        String s2 = DigestUtils.md5Hex(fileInputStream_source);
        if (s2.equals(s1)){
            System.out.println("文件校验完整");
        }

Guess you like

Origin blog.csdn.net/qq_56533553/article/details/129852844