Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск одинаковых файлов в заданной директории, при большом количестве поддиректорий 
:(
    Опции темы
tarasrng
Дата 15.7.2011, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 8.7.2011

Репутация: нет
Всего: нет



здравствуйте. пишу программу, которая ищет все группы одинаковых файлов ненулевого размера в заданной директории и всех вложенных директориях. Одинаковыми нужно считать файлы, у которых одинаковое содержимое. имя файла, атрибуты, и т.д. на сравнение не влияют. 
мой алгоритм такой:
1) получаем список файлов и директорий методом listFiles()

2) проверяем каждый элемент получившегося  массива, если это файл - добавляем его в коллекцию, если директория - выполняем шаг 1 (рекурсия)

 в результате имеем коллекцию со всеми файлами данной директории и поддиректорий, и тут появляется первая проблема: программа ищет файлы в 2 раза дольше, чем проводник windows (если нажать alt+enter на папке)
идем далее:

3) теперь нужно отсортировать нашу коллекцию по размеру файлов
проблема №2
какой метод сортировки использовать?
или может уже при добавлении ставить файл в нужное место, чтобы сразу получить сортированный массив?
я использовал Collections.sort

4) теперь есть сортированный список файлов, и в группах файлов с одинаковым размером сравниваем содержимое. 

все вроде работает, но вот только если файлов сотни тысяч, приходится ждать долго smile 

вот класс, в котором я реализовал выше описанный алгоритм, кроме шага 4

Код



package del;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 *
 * @author RNG
 */
public class calculate implements Comparator{
   // = null;
    ArrayList size = new ArrayList();
    ArrayList path = new ArrayList();
    ArrayList <File> files = new ArrayList();
    public calculate (File dir) {        // получаем каталог, в котором нужно искать файлы

        addFile(dir);
        //System.out.println(files);
        //System.out.println(files.size());
        //System.out.println(size);
        ArrayList <File> s = new ArrayList(sort(files));         //шаг 3
        for (int j=0;j<files.size();j++){

            System.out.print(s.get(j).length());
            System.out.println(s.get(j));

        }
    }
    void addFile(File dir) { 
        System.out.print(" in addFile");
        try

        {   System.out.println(dir);
            File[] flist = new File[dir.listFiles().length];
            System.out.print(" flist created ");

        flist=dir.listFiles();                                              //шаг 1
        System.out.print(dir+" listFiles done ");
        for (int i=0;i<flist.length;i++)
        {
            System.out.print(" in for i="+i+" ");
            if (flist[i].isDirectory())                                           //шаг 2
            {
                System.out.print(" in if ");
                addFile(flist[i]);
            }
            else
            {
                System.out.print(" in else files.size="+files.size());
                if (i<(flist.length)-1)
                    try{
                    System.out.print(" next"+flist[i+1]);
                    }
                    catch (Exception ex)
                    {
                     System.out.print(ex);        
                    }
                files.add(flist[i]);
                System.out.println(flist[i]);
                
            }
        }
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
//            {
//                size.add(flist[i].length());
//                path.add(flist[i].getAbsolutePath());
//            }
           
        
    }
    public int compare (Object o1, Object o2){
        File f1 = (File)o1;
        File f2 = (File)o2;        
        if (f1.length()>f2.length())
            return 1;
        if (f1.length()<f2.length())
            return -1;
        if (f1.length()==f2.length())
            return 0;
        return 0;
    }

    ArrayList sort (ArrayList flist){
        ArrayList sortedList = new ArrayList(flist) ;
        Collections.sort(sortedList, this);

        return sortedList;
    }


}





 
к стати, тестировал программу на папке windows/system32, она на каком то файле зависает, вроде когда питается сделать dir.listFiles()


я новичок в java, подобных проблем не решал, и не знаю, правильно я это делаю. посоветуйте, пожалуйста, что поменять в алгоритме, чтобы поиск был быстрее, или может не теми методами делаю, или вообще нужно другой алгоритм... smile 
прикрепляю файл с исходниками и программой.


Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  _________.rar 22,46 Kb
PM MAIL   Вверх
dorogoyIV
Дата 15.7.2011, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



я думаю так:
 пробежаться по всем папкам, и записать файлы в файл
 читать этот файл, и сравнивать размеры (в какой нибудь коллекции отсортировать)
 теперь уже можно побайтово читать и сравнивать...

а то у тебя все в буфер помещается...
конечно, когда нибудь вылетит OutOffMemory...
PM MAIL   Вверх
Farmazon
Дата 15.7.2011, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Разработчик
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 7.7.2006

Репутация: 1
Всего: 5



долго?... распараллель. вызов addFile ты можешь скармливать в ThreadPoolExecutor виде задания, только коллекцию выбери потокозащищённую...

Добавлено @ 19:24
Collections.sort не устраивает быстродействием?... тогда попробуй посмотреть в сторону TreeSet... Это сортированное множество...

Добавлено @ 19:25
и лучше бы фильтровать файлы сразу и не добавлять их в коллекцию воще...

Это сообщение отредактировал(а) Farmazon - 15.7.2011, 19:26


--------------------
Таково моё общее мнение.
PM MAIL WWW   Вверх
dorogoyIV
Дата 15.7.2011, 19:31 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



Цитата(Farmazon @  15.7.2011,  19:23 Найти цитируемый пост)
и лучше бы фильтровать файлы сразу и не добавлять их в коллекцию воще...

я имел ввиду просто список файлов создать - например <"имя", "размер">, потом сортировать...
PM MAIL   Вверх
Farmazon
Дата 15.7.2011, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Разработчик
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 7.7.2006

Репутация: 1
Всего: 5



распихать по разным группам сразу можно?


--------------------
Таково моё общее мнение.
PM MAIL WWW   Вверх
COVD
Дата 15.7.2011, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

я имел ввиду просто список файлов создать - например <"имя", "размер">, потом сортировать... 

Точнее говоря, коллекцию не обьектов File, а их параметров. Если не ошибаюсь, когда на обьекте File вызывается метод length(), то происходит чтение с диска. Это сильно замедлит сортировку.
PM MAIL   Вверх
dorogoyIV
Дата 16.7.2011, 01:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



Цитата(COVD @  15.7.2011,  21:48 Найти цитируемый пост)
то происходит чтение с диска

я надеюсь не весь файл читается, а только его заголовок (32 или 64 бита)  smile 

кстати в W так и делается.
если запустите поиск, потом в папке %systemroot% найдете список файлов и директорий

Это сообщение отредактировал(а) dorogoyIV - 16.7.2011, 01:37
PM MAIL   Вверх
COVD
Дата 16.7.2011, 03:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



Цитата

я надеюсь не весь файл читается, а только его заголовок 

При сортировке по размеру, если постоянно вызывать этот метод, будет ощутимое замедление. 
PM MAIL   Вверх
dorogoyIV
Дата 16.7.2011, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



COVD, нет.
один раз прочитать, взять имя и размер. записать в коллекцию. (записывать не файлы, а ссылки на файлы)
отсортировать в коллекции по размеру.
затем уже побайтово сравнивать только те файлы, у которых размер одинаков.

я пока не вижу другого способа...  smile 
PM MAIL   Вверх
COVD
Дата 16.7.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 17
Всего: 43



dorogoyIV, я придрался к формулировкам.   smile 
"имя и размер", <"имя", "размер"> - это не "список файлов" и не "ссылки на файлы". Потому, что есть класс File. 
PM MAIL   Вверх
tarasrng
Дата 17.7.2011, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 8.7.2011

Репутация: нет
Всего: нет



Цитата(dorogoyIV @ 16.7.2011,  08:27)
COVD, нет.
один раз прочитать, взять имя и размер. записать в коллекцию. (записывать не файлы, а ссылки на файлы)
отсортировать в коллекции по размеру.
затем уже побайтово сравнивать только те файлы, у которых размер одинаков.

я пока не вижу другого способа...  smile

как это сделать(записать ссылки на файлы в коллекцию)? (напишите кучек кода, если не сложно)

Добавлено через 9 минут и 5 секунд
Farmazon, cори, но я в java еще не асс, и не понял, что Вы имели ввиду. Можно немного объяснить?
Цитата

вызов addFile ты можешь скармливать в ThreadPoolExecutor виде задания, только коллекцию выбери потокозащищённую...

PM MAIL   Вверх
Farmazon
Дата 18.7.2011, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Разработчик
**


Профиль
Группа: Участник
Сообщений: 265
Регистрация: 7.7.2006

Репутация: 1
Всего: 5



уж не побайтно ты ли файлы сравниваешь?... хеш считаешь?...

пример тредпулекзекутора - http://www.javamex.com/tutorials/threads/T...lExecutor.shtml
просто создаёшь пул и пихаешь в него задания(Runnable)




--------------------
Таково моё общее мнение.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0575 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.