Android 加快文件数组的MD5检查

Android 加快文件数组的MD5检查,android,performance,md5,Android,Performance,Md5,我正在遍历一个文件数组,查看其中是否有任何文件与该数组中的最后一个文件匹配: List<File> files = Arrays.asList(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).listFiles()); byte[] md5Downloaded = null; try { md5Downloaded = createCh

我正在遍历一个文件数组,查看其中是否有任何文件与该数组中的最后一个文件匹配:

    List<File> files = Arrays.asList(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).listFiles());
    byte[] md5Downloaded = null;
    try {
        md5Downloaded = createChecksum(files.get(files.size()-1).getAbsolutePath());
    } catch (Exception e1) {
        e1.printStackTrace();
    }

    for(File file : files){

        try {
            byte[] md5CurrentFile = createChecksum(file.getAbsolutePath());


            if(Arrays.equals(md5Downloaded, md5CurrentFile) && counter != files.size()-1 ){
                alertUserMD5(file, files.get(files.size()-1));
                return;
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

然而,我不满意这个过程所花费的时间(大约15秒)。我意识到我正在做的事情在很大程度上取决于列表中文件的数量以及这些文件的大小,但是有没有办法加快速度呢?

看起来您正在尝试确定某个文件是否已经可用。如果这些文件往往是不相关的,您可以只计算前1024个字节的md5,并与最后一个文件进行比较。如果不同,则无需比较整个文件的校验和。只有当它们相等时,才需要比较整个文件的md5

差点忘了:甚至在以前比较过文件大小,如果文件大部分都是不相关的,那么大多数情况下可能会提前退出。

private void searchFile(){
private void searchFile() {
    long t = System.currentTimeMillis();
    List<File> files = new ArrayList<File>(Arrays.asList(dir.listFiles()));
    File downloaded = files.get(files.size() - 1);
    files.remove(files.size()-1);
    byte[] md5Downloaded = null;
    try {
        md5Downloaded = createChecksum(downloaded.getAbsolutePath());
    } catch (Exception e1) {
        e1.printStackTrace();
    }

    Collections.sort(files, new Comparator<File>() {
        @Override
        public int compare(File lhs, File rhs) {
            return Long.valueOf(lhs.length()).compareTo(rhs.length());
        }
    });

    final byte[] MD5 = md5Downloaded;

    final int position = Collections.binarySearch(files, downloaded, new Comparator<File>() {
        @Override
        public int compare(File lhs, File rhs) {
            int compare =  Long.valueOf(lhs.length()).compareTo(rhs.length());
            if (compare == 0) {
                try {
                    if (Arrays.equals(MD5, createChecksum(lhs.getAbsolutePath()))) {
                        return 0;
                    }
                } catch (Exception ignored) {

                }
                return -1;
            } else
                return compare;
        }
    });

    if (position >= 0) {
        alertUserMD5(files.get(position), downloaded);
    }

}
long t=System.currentTimeMillis(); List files=newarraylist(Arrays.asList(dir.listFiles()); 下载文件=files.get(files.size()-1); files.remove(files.size()-1); 字节[]md5download=null; 试一试{ md5Downloaded=createChecksum(下载的.getAbsolutePath()); }捕获(异常e1){ e1.printStackTrace(); } Collections.sort(文件、新比较器(){ @凌驾 公共整数比较(文件lhs、文件rhs){ 返回Long.valueOf(lhs.length()).compareTo(rhs.length()); } }); 最终字节[]MD5=MD5下载; final int position=Collections.binarySearch(文件,下载,新比较器(){ @凌驾 公共整数比较(文件lhs、文件rhs){ int compare=Long.valueOf(lhs.length()).compareTo(rhs.length()); 如果(比较==0){ 试一试{ if(Arrays.equals(MD5,createChecksum(lhs.getAbsolutePath())){ 返回0; } }捕获(忽略异常){ } 返回-1; }否则 返回比较; } }); 如果(位置>=0){ alertUserMD5(files.get(position),下载); } }

对不起,这是一个失败的例子,用“纸”写的。下面是一个工作示例。我已经在578个文件=154毫秒的目录中测试过了,我无法得到这个位置的非负数。谢谢。尺寸比较的建议帮我把时间缩短到4秒左右。
private void searchFile() {
    long t = System.currentTimeMillis();
    List<File> files = new ArrayList<File>(Arrays.asList(dir.listFiles()));
    File downloaded = files.get(files.size() - 1);
    files.remove(files.size()-1);
    byte[] md5Downloaded = null;
    try {
        md5Downloaded = createChecksum(downloaded.getAbsolutePath());
    } catch (Exception e1) {
        e1.printStackTrace();
    }

    Collections.sort(files, new Comparator<File>() {
        @Override
        public int compare(File lhs, File rhs) {
            return Long.valueOf(lhs.length()).compareTo(rhs.length());
        }
    });

    final byte[] MD5 = md5Downloaded;

    final int position = Collections.binarySearch(files, downloaded, new Comparator<File>() {
        @Override
        public int compare(File lhs, File rhs) {
            int compare =  Long.valueOf(lhs.length()).compareTo(rhs.length());
            if (compare == 0) {
                try {
                    if (Arrays.equals(MD5, createChecksum(lhs.getAbsolutePath()))) {
                        return 0;
                    }
                } catch (Exception ignored) {

                }
                return -1;
            } else
                return compare;
        }
    });

    if (position >= 0) {
        alertUserMD5(files.get(position), downloaded);
    }

}