Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 [2] 3  Все   Вниз
  Печать  
Автор Тема: Программа для поиска повторяющихся текстовых файлов  (Прочитано 26187 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Dmytry
Гость
« Ответ #30 : 29-11-2009 12:45 » 

Код:
foreach (DictionaryEntry d in myhash)
            {
                // Заносим все элементы из списка d.Value в ListBox
                listBox2.Items.Add(d.Value);
            }

вот вроде сделал так как ты сказал, но выдает ошибку:
Error   1   A local variable named 'd' cannot be declared in this scope because it would give a different meaning to 'd', which is already used in a 'parent or current' scope to denote something else   E:\SPZ\курсовой (дубликат)\kursovoy\kursovoy\Form1.cs   153   38   kursovoy

Не погу понять что это может быть Жаль
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #31 : 29-11-2009 12:49 » 

Просто у тебя уже есть одна переменная с таким именем в функции. Назови как-нибудь по-другому. И - не уверен, что Add в этом случае сработает именно так. Думаю, надо использовать AddRange вместо Add - ты же целый список добавляешь.
Записан
Dmytry
Гость
« Ответ #32 : 29-11-2009 12:58 » 

переделал и добавил AddRange как ты сказал:
Код:
foreach (DictionaryEntry val in myhash)
                {
                    // Заносим все элементы из списка d.Value в ListBox
                    listBox2.Items.AddRange(val.Value);
                }

Но AddRange не принимает ,пишет:
Error   1   The best overloaded method match for 'System.Windows.Forms.ListBox.ObjectCollection.AddRange(System.Windows.Forms.ListBox.ObjectCollection)' has some invalid arguments   E:\SPZ\курсовой (дубликат)\kursovoy\kursovoy\Form1.cs   154   21   kursovoy
Error   2   Argument '1': cannot convert from 'object' to 'System.Windows.Forms.ListBox.ObjectCollection'   E:\SPZ\курсовой (дубликат)\kursovoy\kursovoy\Form1.cs   154   45   kursovoy
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #33 : 29-11-2009 13:07 » 

Всего-навсего не выполнено приведение типа, возвращаемого DictionaryEntry.Value (тип object) к типу, требуемому AddRange. Попробуй
Код:
foreach (DictionaryEntry val in myhash)
                {
                    // Заносим все элементы из списка d.Value в ListBox
                    listBox2.Items.AddRange( (ArrayList)val.Value );
                }

Ну и английский язык учить надо Ага Основная масса документации по программированию - на английском. Вот и компилятор, как видишь, обычно этот язык предпочитает Улыбаюсь
Записан
Dmytry
Гость
« Ответ #34 : 29-11-2009 13:56 » 

Нет. То же самое :
Error   1   The best overloaded method match for 'System.Windows.Forms.ListBox.ObjectCollection.AddRange(System.Windows.Forms.ListBox.ObjectCollection)' has some invalid arguments   E:\SPZ\курсовой (дубликат)\kursovoy\kursovoy\Form1.cs   154   17   kursovoy
Error   2   Argument '1': cannot convert from 'System.Collections.ArrayList' to 'System.Windows.Forms.ListBox.ObjectCollection'   E:\SPZ\курсовой (дубликат)\kursovoy\kursovoy\Form1.cs   154   42   kursovoy

Слушай, а ты просматривал тот код программы в целом, что я выложил? Может, я там что не так сделал??
« Последнее редактирование: 29-11-2009 14:27 от Sel » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #35 : 29-11-2009 14:08 » 

Нет, в данном случае нужно просто найти способ, как добавить элементы в список, поскольку AddRange не хочет воспринимать тип ListArray.
Например, попробовать
Код:
listBox2.Items.AddRange( ((ArrayList)val.Value).ToArray() );
Хотя это не очень оптимальное решение. Другим вариантом может быть вложенный цикл
Код:
foreach(string pathToFile in (ArrayList)val.Value)
{
    listBox2.Items.Add(pathToFile);
}
« Последнее редактирование: 29-11-2009 14:11 от Вад » Записан
Dmytry
Гость
« Ответ #36 : 29-11-2009 14:19 » 

"listBox2.Items.AddRange( ((ArrayList)val.Value).ToArray() );"  - тоже не помогло:(
 Твое "Нет" означало, что я все правильно написал или что ты не смотрел мой код?

Вложенный цикл, в смысле так?
Код:
foreach (DictionaryEntry val in myhash)
            {
                // Заносим все элементы из списка d.Value в ListBox
                foreach (string pathToFile in (ArrayList)val.Value)
                {
                    listBox2.Items.Add(pathToFile);
                }
            }

Если да, то так тоже не помогает Жаль Жаль Жаль....а может, мне, например, попробовать мое val.Value забить в новый список и потом его вывести например
Код:
newarray.Add(val.Value)
for(j=0;j<c;j++)
{
 listBox2.Items.Add(newarray[j]);
}
Не понял
« Последнее редактирование: 29-11-2009 14:26 от Sel » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #37 : 29-11-2009 14:31 » 

Я посмотрел твой код, но не очень внимательно. Сейчас пересмотрел ещё раз. Вопрос:
Код:
Hashtable myhash = new Hashtable();//створення хеш-таблиці
- почему это выполняется в цикле, где перебираются файлы?
Записан
Dmytry
Гость
« Ответ #38 : 29-11-2009 14:39 » 

"где перебираются файлы?" - В Смысле файлы из хэш таблицы? Или вообще файлы, хэши которых нужно найти?
 И то, и другое перебирается в цикле foreach (FileInfo file in files).
 вот:
Код:
foreach (FileInfo file in files)
            {

                // Ім'я нового файлу
                string nameFileLab2 = file.Name;// переменная хранящая имя фалйов
                string pathoffile = file.DirectoryName;//переменная хранящая пути к файлам
                // Шлях до файлу
                string pathFileLab2 = System.IO.Path.Combine(pathoffile, nameFileLab2);
                // Читання файлу
                string contents2 = System.IO.File.ReadAllText(pathFileLab2);

                hash2 = getMd5Hash(contents2);///беру хэш файла
                fileHashes.Add(hash2);// это заносил в список хеэши , но по твое рекомендации ее не применял а только использовал для проверки работы вычисления хэша



                //запис до хеш-таблиці//
                
                // добавляем лист для ключа key1, если его ещё нет
                if (!myhash.Contains(hash2))
                {
                    myhash.Add(hash2, new ArrayList());
                }
                // добавляем значение пути в ключ
                myhash[hash2] = file.DirectoryName;
                
         }

насчет
Код:
Hashtable myhash = new Hashtable();//створення хеш-таблиці
-понял твое замечание и вынес его за цикл
« Последнее редактирование: 29-11-2009 15:06 от Sel » Записан
Dmytry
Гость
« Ответ #39 : 29-11-2009 15:52 » 

Блин хоть застерлись не могу понять..почему не работает:(ЖальЖаль
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #40 : 29-11-2009 17:08 » 

Как именно выглядит проблема? И покажи свежую версию кода функции.
Записан
Dmytry
Гость
« Ответ #41 : 29-11-2009 17:31 » 

проблема та же - с выводом дубликатов в отсортированном порядке:
вот код свежего обновления:
Код:
Hashtable myhash = new Hashtable();

            //Читання масиву файлів та знаходження хешів цих файлів і додавання його у новий список fileHashes          
            foreach (FileInfo file in files)
            {

                // Ім'я нового файлу
                string nameFileLab2 = file.Name;// переменная хранящая имя фалйов
                string pathoffile = file.DirectoryName;//переменная хранящая пути к файлам
                // Шлях до файлу
                string pathFileLab2 = System.IO.Path.Combine(pathoffile, nameFileLab2);
                // Читання файлу
                string contents2 = System.IO.File.ReadAllText(pathFileLab2);

                hash2 = getMd5Hash(contents2);///беру хэш файла
                fileHashes.Add(hash2);// это заносил в список хеэши , но по твое рекомендации ее не применял а только использовал для проверки работы вычисления хэша



                //запис до хеш-таблиці//
                // добавляем лист для ключа key1, если его ещё нет
                if (!myhash.Contains(hash2))
                {
                    myhash.Add(hash2, new ArrayList());
                }
                    // добавляем значение пути в ключ
                    myhash[hash2] = file.Name;      
            }
            foreach (DictionaryEntry val in myhash)
            {
                // Заносим все элементы из списка val.Value в ListBox
                foreach (string pathToFile in (ArrayList)val.Value)
                {
                    listBox2.Items.Add(pathToFile);
                }
            }        
                
          
            

 И вопрос еще - а то что список  val.Value выведется отсортированным - это какое то свойство по умолчанию?..ну то есть какая гарантия что он точно выведется отсортированным?
« Последнее редактирование: 29-11-2009 17:45 от Dmytry » Записан
Dmytry
Гость
« Ответ #42 : 29-11-2009 17:50 » 

И еще возможно ли провернуть такую махинацию..допустим забить хеш-таблицу ключами и соотвецтвенными  путями к файлам, потом отсортировать список ключей и что бы пути привязаны к своим ключам тоже как бы  отсортировались??
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #43 : 29-11-2009 18:33 » 

а вот это точно работает?
Код:
                    // добавляем значение пути в ключ
                    myhash[hash2] = file.Name;     
мне кажется, проблема здесь - похоже, ты устанавливаешь имя файла в качестве значения, заменяя при этом список.

Что касается сортированного списка - если нужен точно сортированный, можно посмотреть другие контейнеры (например, HashSet) или сделать ещё один проход по хэш-таблице и выполнять сортировку.

А так - сортировка, должно быть достигается тем, что исходный список файлов в директории уже отсортирован, а добавление в таблицу производится в тот же порядок.
Записан
Dmytry
Гость
« Ответ #44 : 29-11-2009 19:16 » 

Код:
// добавляем значение пути в ключ
                    myhash[hash2] = file.Name;     

Насчет этого -дело в том ,что когда ты писал вместо этой строки
Код:
myhash["key1"].Add("C:\\Text1.txt")
- то такую команду не воспринимает компилятор. я попробовал переделать ее так:
Код:
myhash.Add("key1","C:\\Text1.txt")
  -тогда после тестирования мне написало что ключ уже есть в списке ключей
Записан
Dmytry
Гость
« Ответ #45 : 29-11-2009 19:53 » 

Цитата
"Сделать ещё один проход по хэш-таблице и выполнять сортировку."

А как это сделать? Как заставить значения жестко привязаться к своим ключам и при сортировке ключей чтОБы и значения менялись с ними?
« Последнее редактирование: 29-11-2009 19:55 от Sel » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #46 : 29-11-2009 20:15 » 

Насчет этого -дело в том ,что когда ты писал вместо этой строки
Код:
myhash["key1"].Add("C:\\Text1.txt")
- то такую команду не воспринимает компилятор. я попробовал переделать ее так:
Код:
myhash.Add("key1","C:\\Text1.txt")
 -тогда после тестирования мне написало что ключ уже есть в списке ключей
Всё ясно. Опять всё дело в типах - Hashtable приводит всё к object, и нужно это учитывать. Вот за это я не люблю java и C# и предпочитаю пользоваться там generic-типами, если есть возможность. Ну да ладно, применительно к этой ситуации, думаю, нужно было всего лишь выполнить приведение типа.
Код:
((ArrayList) myhash["key1"]).Add("C:\\Text1.txt")
Твоя модификация содержала ошибку - она добавляла путь не к списку, хранящемуся как значение ключа, а в качестве самого этого значения. Приведение значения к объекту object позволяло это делать незаметно.

Кстати, поглядел - generic-эквивалентом хэштаблицы, насколько могу судить, является коллекция System.Collections.Generic.Dictionary, имеющая два параметра шаблона - тип ключа и тип значения.

Для сортировки посмотри в сторону метода Sort у ArrayList
« Последнее редактирование: 29-11-2009 20:17 от Вад » Записан
Dmytry
Гость
« Ответ #47 : 30-11-2009 14:31 » 

Работает ты лучший!!!! Класс! Класс! Класс! Класс!.Но вот ,только как мне теперь можно переделать что  бы выводило только дубликаты???
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #48 : 30-11-2009 15:00 » 

После цикла обработки файлов у тебя в hashtable теперь лежат пути, сгруппированные по дубликатам. Как именно ты их хочешь выводить, в один общий список?

В любом случае, теперь в каждом myhash[<ключ>] лежит список с дубликатами. То есть, пройдя по хэштаблице, ты можешь извлечь любую группу дубликатов и сделать с ней что угодно (я бы, возможно, выводил не в ListBox, а в дерево - TreeView, кажется).

Собственно, возвращаемся теперь к коду
Код:
foreach (DictionaryEntry val in myhash)
{
    // Заносим куда-то элементы из списка (ArrayList)(d.Value) - набор дубликатов одного файла
}
Записан
Dmytry
Гость
« Ответ #49 : 30-11-2009 15:04 » 

Цитата
"После цикла обработки файлов у тебя в hashtable теперь лежат пути, сгруппированные по дубликатам. Как именно ты их хочешь выводить, в один общий список?"
Да, хотел в один общий список, чтОБы были только дубликаты, ну или на края, допустим, выводить все файлы, но дубликаты как-то отделять (допустим, пунктирной линией или надписью "Группа дубликатов")
« Последнее редактирование: 30-11-2009 15:06 от Sel » Записан
Dmytry
Гость
« Ответ #50 : 30-11-2009 15:16 » 

А может нужно при выводе просто поставить лимит элементов  выводимых списков ,допустим, если в списке будет больше одного элемента, тогда их выводить?
Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #51 : 30-11-2009 15:24 » 

Dmytry, да, если нужны только дубликаты - выводи только список из >1 элемента. Проверяется элементарно - у ArrayList есть свойство Count.
Код:
foreach (DictionaryEntry val in myhash)
{
    ArrayList lst = (ArrayList)(d.Value);
    if (lst.Count > 1)
    {
        // Заносим куда-то элементы из списка (ArrayList)(d.Value) - набор дубликатов одного файла
    }
}
Записан
Dmytry
Гость
« Ответ #52 : 30-11-2009 15:32 » 

Почему-то не может распознать lst   Не понял
В строчке:
Код:
ArrayList lst
« Последнее редактирование: 30-11-2009 15:33 от Sel » Записан
Dmytry
Гость
« Ответ #53 : 30-11-2009 15:55 » 

Так, все исправил. Все работает! Спасибо тебе огромное! Я тебе, наверно, уже полжизни должен. Половина работы сделана. Теперь нужно сделать то, о чем я уже вспоминал -  при нажатии мышью на любой из дубликатов - он должен открываться в блокноте. Ты вспоминал о некой ShellExecute и что ее нужно импортировать в С#. Значит, мне нужно посмотреть  аналоги этой функции в MSDN.
Еще один нюанс - сейчас у меня стоит вывод путей дубликатов в ListBox, то есть, в  hashtable  лежат пути, но мне по условию нужно чтОБ выводились имена дубликатов. Могу изменить параметр, чтобы в hashtable заносились имена, но, как я помню, именно пути к файлам нам необходимы для того, чтобы сделать запуск файлов через блокнот, так так мне лучше поступить?
« Последнее редактирование: 30-11-2009 16:07 от Sel » Записан
Dmytry
Гость
« Ответ #54 : 30-11-2009 17:26 » 

По поводу ShellExecute - вот, вроде как, нашел аналог ему на С#.
http://msdn.microsoft.com/ru-ru/library/system.diagnostics.processstartinfo.aspx

По-моему, оно. Хотя, может у тебя есть другие предложения, как реализовать поставленную задачу открытия файлов-дубликатов с помощью блокнота?
« Последнее редактирование: 30-11-2009 18:09 от Sel » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #55 : 30-11-2009 21:20 » 

Не совсем, но в целом - похоже, System.Diagnostics.Process подойдёт. Попробуй. Примеры там есть.

Насчёт более красивого отображения - надо смотреть документацию на ListBox (позволяет ли он, помимо текста, задавать ещё ссылку на вспомогательные данные).
« Последнее редактирование: 30-11-2009 21:25 от Вад » Записан
Dmytry
Гость
« Ответ #56 : 01-12-2009 13:19 » 

Спасибо за совет.Буду разбираться.
Записан
Dmytry
Гость
« Ответ #57 : 01-12-2009 14:24 » 

Смотрел документацию про ListBox. Того, что ты говорил, вроде бы, не нашел Здесь была моя ладья.... Посмотрел про процессы - первый пример пробовал -  не получился, второй (со статическим методом Start.) - работает (лучше всего - функция  OpenWithArguments()).  Но я пробовал его как отдельную программу. Дело в том, что там прописывается полный путь с именем файла. У меня же при выводе в ListBox имени файла в пути нет. То есть, насколько я понял, нужно будет еще как-то приписывать имя файла к пути, и вот что надумал: А если в Hashtable будут хранится не только пути в файлам, а элементы всего массива files, который имеет тип FileInfo, а значит, сохранит параметры и имена файлов и их пути??
« Последнее редактирование: 01-12-2009 18:32 от Sel » Записан
Вад
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #58 : 01-12-2009 15:47 » 

В таком подходе есть один изъян: понадобится выполнять поиск в hashmap при выборе файла в ListBox. Вот если облегчить этот поиск...
Вообще, списки должны обеспечивать подобную функциональность. Только, наверное, не ListBox. Погляди ListView (а возможно, даже лучше будет TreeView - тогда можно будет дубликаты разложить по разным веткам дерева).
Записан
Dmytry
Гость
« Ответ #59 : 01-12-2009 16:21 » 

Вот нашел информацию про
http://msdn.microsoft.com/ru-ru/library/system.windows.forms.listview.aspx

Вот:
Цитата
Например, можно использовать элемент управления ListView для отображения списка файлов, которые затем могут быть открыты и использованы приложением. Пользователь может выделить файлы, предназначенные для открытия, а затем дважды щелкнуть их, чтобы активировать эти элементы и открыть файлы в приложении.
-это, вроде бы, оно?
« Последнее редактирование: 01-12-2009 18:30 от Sel » Записан
Страниц: 1 [2] 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines