md5的比较

众所周知,可以通过md5来比较两个文件是否一样,在我写demo的时候发生了一个错误,用两个方法来比较两个文件,方法2能比较成功,但是方法一比较失败。
注意:test是原来的视频文件,test2是经过分块再合并的文件。两个都可以正常播放,数据大小一致。

//方法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("文件校验完整");
        }

经过查找资料
第一种方式计算两个副本的 MD5 值,而两个副本的 MD5 值不同,那么可能是由于两个副本的元数据不同。元数据包括文件的创建时间、修改时间、访问时间等信息,如果这些信息不同,计算出来的 MD5 值也会不同。
第二种方式计算两个副本的 MD5 值,而两个副本的 MD5 值相同,那么可能是由于两个副本的元数据相同,或者只有元数据不同,而文件内容相同。因为第二种方式只计算文件的内容,而不考虑元数据的差异。
总结:比较文件是否一致,一般都是比较内容,尽量使用流来操作,流的操作虽然io慢但是占用内存小,而直接读取文件的方法相反。

   //测试分块
    @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 fileList = Arrays.asList(files);
        //对分块文件进行排序
        Collections.sort(fileList, new Comparator() {
            @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("文件校验完整");
        }

你可能感兴趣的:(java,IO,java)