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

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

Всем привет!У меня возникла такая проблема. Мне нужно написать программу в Visual studio 2008, которая выполняет поиск дублирующихся файлов в каталоге или на логическом диске. программа должна предоставлять следующие возможности:
·   выполнение поиска файлов, которые дублируются, в заданном пользователем адресном пространстве (логическом диске или каталоге);
·   сообщение пользователя о найденных дубликатах; возможность навигации между ними;
·   сжатие файлов-дубликатов за алгоритмом GZIP.
 Общие требования интерфейса программы (обязательные элементы):
·   поле введения адресного пространства, в котором будет выполняться поиск дубликатов;
·   форма с перечнем найденных файлов, которые дублируются, с возможностью их открытия прямо из дополнения (например, двойным нажатием левой кнопки мыши);
·   если несколько текстовых файлов имеют дубликаты, то они должны каким-то образом группироваться; например, на диске присутствуют два одинаковых файла - С:\doc\text1.txt но C:\temp\my\text11.txt, а также на этом диске есть еще три файла, которые дублируются, - С:\doc\text2.txt, C:\temp\text.txt но C:\temp\my\text2.txt; тогда пользователю должны представиться две группы файлов, которые дублируются, - text1.txt и text2.txt (названия групп могут быть любые); причем пользователь должен иметь возможность самому избрать из группы файл-оригинал и файл(и) -дублікати;
·   у пользователя должна быть возможность сжатия дубликатов за алгоритмом GZIP (за его желанием).

На данном этапе у меня имеется следующее:
Есть исходник написанного мной куска программы на С#:
вот он http://files.mail.ru/LC6PT7

На данном этапе моя программа по задающемуся пользователем пути отыскивает в каталогах текстовые файлы (*.txt), находит по алгоритму md5 хэш каждого файла сводя их в массив строк и выводя в отдельном текстовом поле формы программы(listbox1). Так вот у меня возникла проблема с тем ,что б потом из полученного масcива из хэшов найти одинаковые строки, свести их в новый массив и вывести в другое строковое поле listbox2.

Может кто-нибудь подскажет как решить мою проблему?...буду премного благодарен. Дело в том что я застрял даже на том ,что не могу получить элементарный контроль над массивом - пытался вывести первую строку...ничего не получилось -почему то выводило все строки сразу.
Записан
Вад
Команда клуба

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

« Ответ #1 : 24-11-2009 21:44 » 

Бегло глянул код. Мне кажется, ты слегка забегаешь вперёд. Скажем, я не вижу оснований для того, чтобы сразу помещать значения в listbox - очевидно же, с ними потом будет неудобно работать. Поскольку listbox предназначен не для работы с данными, а для предоставления интерфейса. Поэтому функционально он сильно ограничен: ведь главное, что от него требуется, - рисовать список и реагировать на всякие клики в нём.

Если хочешь удобно работать с данными - изолируй собственно обработку от интерфейса. И выводи уже конкретные полученные результаты - хоть в тот же listbox - но уже после того, как все необходимые манипуляции произведены.

В твоём случае для первичной группировки хорошо подошла бы ассоциативная коллекция. Не знаю, есть ли в C# аналог multimap - но это было бы то, что надо для данной задачи. Если такого нет, можно взять Hashtable и использовать md5 в качестве ключа и какой-нибудь ArrayList для хранения списка значений.
Ну и потом уже простеньким вложенным foreach можно хоть просто в столбик вывести значения, хоть разбив по группам.
« Последнее редактирование: 24-11-2009 21:46 от Вад » Записан
RXL
Технический
Администратор

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

WWW
« Ответ #2 : 25-11-2009 06:51 » 

Вад, и еще надо сассоциировать строки в ListBox с идентификаторами map или напрямую с указателями.  Опять же - не в курсе, как это в .NET реализовано. Иначе будут трудности с одноименными строками, если искать в map по ним.
« Последнее редактирование: 26-11-2009 17:00 от Sel » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Dmytry
Гость
« Ответ #3 : 25-11-2009 12:13 » 

Спасибо огромное за советы!!!....Я вот тут нашел ссылку
http://msdn.microsoft.com/ru-ru/libr...hashtable.aspx

Пытался вникнуть но не совсем уловил смысл: я так понял что у тебя будет список ключей md5 и список имен файлов ,которые принадлежат этим md5...То есть между ними образуется взаимосвязь и я смогу задавая например md5 сразу выводить имя файла ,что ему принадлежит?...но я не совсем понимаю, того как я буду забывать md5 именно массив ключей?....то есть мне сначала нужно будет найти md5 и потом занести их в массив ключей?..а как же потом они будут распознавать какому md5 соотвецтвует имя файла? 

Записан
Вад
Команда клуба

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

« Ответ #4 : 25-11-2009 12:57 » 

Смотри. У тебя есть таблица, в которой хранятся пары "ключ-значение". Ключ - это вычисленный хэш. Для файлов-дубликатов хэш одинаковый.
Стало быть, для одного вычисленного значения хэша существует один или более файлов (иначе откуда вообще взялось такое значение, как не из обсчёта функции для файла?).

Тогда возникает вопрос: как хранить список файлов, у которых одинаковый хэш? Самое простое решение, которое я вижу, - это хранить список файлов именно что в виде списка. Например, ArrayList<string>. И тогда можно для каждого значения md5 завести такой список. А организовать хранение списков - в ассоциативном массиве.

В общем, получается что-то вроде Hashtable<string, ArrayList<string> > - то есть, в таблице мы храним пары "<md5-строка>-<список путей к файлам>". Тогда при вычислении очередного хэша для очередного файла требуется лишь найти вычисленный хэш в таблице. Если есть - то добавить путь к значению (списку путей). Если нет - создать новый список, содержащий путь к файлу, и добавить в hashtable.

Соответственно, файлы сразу оказываются сгруппированы по дубликатам. В каждой ячейке таблицы хранится список эквивалентных между собой файлов.

Как я уже говорил, более удобной структурой был бы аналог multimap - там группировать не надо, поскольку позволяется хранить несколько значений с одинаковым ключом непосредственно в контейнере. Поэтому нет нужды надстраивать массив, и делать поиск по имени файла в такой структуре попроще.
« Последнее редактирование: 25-11-2009 13:00 от Вад » Записан
Dmytry
Гость
« Ответ #5 : 25-11-2009 14:56 » 

Спасибо огромное буду разбираться Класс!...Тока вот у меня еще парочка вопросиков:

1) Я так понял что мой алгоритм - кусок клда по нахождению хэша файла я оставляю..потом создаю Hashtable<string, ArrayList<string> >...в  string записываю результаты нахождения хеша. А в  ArrayList<string записываю список путей к файлам?Не понял

Я просто не очень если честно понял вот это(извините за мою не отесаность просто у меня не такие серьезные и большие познания в программировании):
"Тогда при вычислении очередного хэша для очередного файла требуется лишь найти вычисленный хэш в таблице. Если есть - то добавить путь к значению (списку путей). Если нет - создать новый список, содержащий путь к файлу, и добавить в hashtable. "

Записан
Вад
Команда клуба

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

« Ответ #6 : 25-11-2009 15:10 » 

1) Я так понял что мой алгоритм - кусок клда по нахождению хэша файла я оставляю..потом создаю Hashtable<string, ArrayList<string> >...в  string записываю результаты нахождения хеша. А в  ArrayList<string записываю список путей к файлам?Не понял
Да, всё так: в hashtable ключом служит md5-хэш, а в списках хранятся пути к файлам.

А дальше всё просто. Hashtable - это, если брать совсем грубо, просто такая таблица, в которой каждому ключу-идентификатору соответствует значение (в нашем случае - список путей). Hashtable предоставляет возможность доступа к значению по ключу. Поиск при этом занимает сравнительно мало времени.

Лучше я на грубом примере. Вот, скажем, у меня есть hashtable, где ключ - некоторая строка, а значение - другая строка (для простоты. на её месте может быть хоть массив, хоть что угодно). Код схематический, так что 100% корректность не гарантирую, просто общая идея:
Код:
Hashtable <string, string> myhash;
// добавляем значения:
myhash.Add("sunday", "7");
myhash.Add("monday", "1");
// ... и так далее

string number = myhash["sunday"]; // - получаем значение по ключу
Если в качестве значения хранился бы массив - можно было бы получать к нему доступ абсолютно аналогично, и затем вызывать нужные методы. Например, что-то вот такое:
Код:
Hashtable <string, ArrayList<string> > myhash2;
// как-то заполняем
myhash2.Add("key", new ArrayList<string>()); // допустим, как-то так создаём новый список для нового ключа
// ...
// добавляем элемент к существующему массиву
myhash2["key"].Add("c:/temp/1.txt");
В общем, смотри примеры манипулирования. Как проверить, существует ли элемент. Как добавить элемент. Как получить доступ к существующему элементу.
« Последнее редактирование: 25-11-2009 15:20 от Вад » Записан
Dmytry
Гость
« Ответ #7 : 25-11-2009 15:35 » 

Понял тебя. Буду вникать. Cпасибо!!! Класс!

А вот еще вопросик (может, он, конечно, покажется глупым, но все же):
 
Что будет лежать конкретно в массиве listarray?? Что реальные пути к файлам??? То есть, ну допустим, D:\file\.... вот у меня просто в программе есть массив типа FileInfo[] files, в который хранит список файлов в каталоге. С помощью foreach я получаю доступ к, насколько я понял, подмаСсиву  file.Name, который содержит имена файлов. Потом, используя этот массив, я читаю файлы и нахожу ИХ хэши. Так, а здесь тогда получается, тоже будет он -  file.Name или весь массив FileInfo[] files???
« Последнее редактирование: 26-11-2009 17:04 от Sel » Записан
Вад
Команда клуба

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

« Ответ #8 : 25-11-2009 18:55 » 

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

То есть, берёшь список файлов в каталоге и сразу считаешь хэши и добавляешь результат в таблицу.
Записан
Dmytry
Гость
« Ответ #9 : 25-11-2009 18:59 » 

Понял..спасибо за ответ!!! Класс!
Записан
Dmytry
Гость
« Ответ #10 : 26-11-2009 06:40 » 

Блин, у меня появилась реальная проблема.... Мой алгоритм вычисления хэша некорректно работает Жаль Получается, он работае,т если текстовые файлы лежат в том каталоге, что я задаю непосредственно.... Если же в заданНом мною каталоге лежат еще, допустим, 2 каталога и в них потом уже - искомые мною файлы - то все, программа не работает... Не могу никак понять ,что мне нужно подправить, чтоб все заработало Жаль

вот код:
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.IO;
using System.Collections;
namespace kursovoy
{
    
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        static string getMd5Hash(string input)
        {
            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 md5Hasher = MD5.Create();

            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data
            // and format each one as a hexadecimal string.
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        // Verify a hash against a string.
        static bool verifyMd5Hash(string input, string hash)
        {
            // Hash the input.
            string hashOfInput = getMd5Hash(input);

            // Create a StringComparer an comare the hashes.
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //Create a new hash table.
        Hashtable myhash = new Hashtable();


        private void button1_Click(object sender, EventArgs e)
        {

            
          
            // Каталог для створення файлів проекту
            string ProjDir = textBox1.Text;

            //Отображение файлов в каталоге
            string searchPattern = @"*.txt";

            DirectoryInfo di = new DirectoryInfo(ProjDir);
            DirectoryInfo[] directories =
                di.GetDirectories(searchPattern, SearchOption.AllDirectories);

            FileInfo[] files =
                di.GetFiles(searchPattern, SearchOption.AllDirectories);

            foreach (DirectoryInfo dir in directories)
            {
                listBox2.Items.Add(dir.FullName);
            }
            //Объявление переменных
            string source2;
            string hash2;
            List<string> fileHashes = new List<string>();

            //string[] array1=new string[100];
            int j ;
            int c = files.Length; ;//длина массива из файлов в заданном каталоге то есть количество файлов
            int d = directories.Length;//длина массива из путей директорий то есть количество каталогов


            foreach (FileInfo file in files)
            {
                for (j = 0; j < d; j++)
                {
                    // Ім'я нового файлу
                    string nameFileLab2 = @file.Name;

                    // Шлях до файлу
                    string pathFileLab2 = System.IO.Path.Combine(ProjDir, nameFileLab2);

                    // Читання файлу
                    string contents2 = System.IO.File.ReadAllText(pathFileLab2);


                    source2 = contents2;
                    hash2 = getMd5Hash(source2);

                    fileHashes.Add(hash2);

                    listBox2.Items.Add(hash2);
                }
                
                
            }
            
    

            listBox1.Items.Add(c);
            listBox1.Items.Add(d);
          
        
               for (j = 0; j < c; j++)
            {
                myhash.Add(fileHashes[j], files[j]);
            }
            
            listBox1.Items.Add(myhash[fileHashes[0]]);
        }
  

        private void button2_Click(object sender, EventArgs e)
        {
            
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
}
}

« Последнее редактирование: 26-11-2009 17:00 от Sel » Записан
Вад
Команда клуба

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

« Ответ #11 : 26-11-2009 07:48 » 

Ты берёшь файлы только из текущей директории. Чтобы обработать вложенные - нужно взять эти директории и спуститься в них рекурсивно.

Лучше выделить обработку файлов в директории в отдельную функцию и передавать в неё путь к директории в качестве параметра. А внутри вызывать для всех поддиректорий ту же самую функцию рекурсивно.
Разумеется, при каждом новом вызове функция должна накапливать получаемые данные в одном и том же месте. То есть, список файлов придётся либо сделать полем класса, либо передавать в качестве параметра функции.
Записан
Dmytry
Гость
« Ответ #12 : 26-11-2009 17:56 » 

Спасибо за совет Класс!...Но я тут пошарил и с помощью оссобеностей С шарпа сделала намного проще:
вот код:
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.IO;
using System.Collections;
namespace kursovoy
{
   
    public partial class Form1 : Form
    {
       
        public Form1()
        {
            InitializeComponent();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        static string getMd5Hash(string input)
        {
            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 md5Hasher = MD5.Create();

            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data
            // and format each one as a hexadecimal string.
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        // Verify a hash against a string.
        static bool verifyMd5Hash(string input, string hash)
        {
            // Hash the input.
            string hashOfInput = getMd5Hash(input);

            // Create a StringComparer an comare the hashes.
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //Create a new hash table.
       


        private void button1_Click(object sender, EventArgs e)
        {


            //Объявление переменных
            string source2;
            string hash2;
            List<string> fileHashes = new List<string>();
            List<string> pathtodir = new List<string>();
            //string[] array1=new string[100];
           
            // Каталог для створення файлів проекту
            string ProjDir = textBox1.Text;

            //Отображение файлов в каталоге
            string searchPattern = "*.txt";

            DirectoryInfo di = new DirectoryInfo(@ProjDir);
            DirectoryInfo[] directories =
                di.GetDirectories("*", SearchOption.AllDirectories);

            FileInfo[] files =
                di.GetFiles(searchPattern, SearchOption.AllDirectories);
            int j;
            int c = files.Length;
            int d = directories.Length;
           
            foreach (DirectoryInfo dir in directories)
            {
             
                //listBox2.Items.Add(dir.FullName);
                pathtodir.Add(dir.FullName);
            }
           


            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);
                   
                    source2 = contents2;
                    hash2 = getMd5Hash(source2);

                    fileHashes.Add(hash2);
                    //listBox2.Items.Add(hash2);
           
               
               
        }
           
   

            listBox3.Items.Add(c);
            listBox4.Items.Add(d);
            //fileHashes.Sort();
            string[] keyarray = new string[c];
            fileHashes.CopyTo(keyarray);
            for (j = 0; j < c; j++)
            {
                listBox2.Items.Add(files[j]);
                listBox1.Items.Add(keyarray[j]);
            }

            Hashtable myhash = new Hashtable();
            for (j = 0; j < c; j++)
            {
                myhash.Add(keyarray[j], files[j]);
               
                listBox1.Items.Add(myhash[fileHashes[j]]);
            }
           
            //listBox1.Items.Add(myhash[fileHashes[0]]);
        }
 

        private void button2_Click(object sender, EventArgs e)
        {
           
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void listBox3_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void listBox4_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
}
}



Теперь перехожу непосредственно к составлению таблицы хэшей как ты и сказал...создал метод Hashtable...начал заполнять его масивом который хранит ключи и списком который хранит список файлов...Попытался по ключу  найти соотвецтвующий ему файл...а оно мне выдало ошибку мол значение ключа уже забито в  словарь массива  ключей таблицы, то есть я так понял я пытаюсь добавить ключи в таблицу, которая их уже содержит.Посмотрел по коду - вроде как нигде до этого не заносил значения этих ключей.пробовал вывести файл по ключу не добавляя предварительно их в таблицу(то есть без строчки myhash.Add(keyarray, files[j])) -пишет что нет что выводить...что массив , как я понял из файлов пуст...в чем может быть проблема ,что ключи уже есть в словаре таблицы...может его нужно очистить сначала  а потом заполнить по новому? 
Записан
Sel
Злобный
Администратор

ru
Offline Offline

« Ответ #13 : 26-11-2009 18:43 » 

Dmytry, ты обратил внимание, что я правлю почти каждый твой пост?? Почини, наконец, свою клавиатуру, чтобы многоточия не лепила где попало, и научись расставлять знаки препинания (это "точки" и "запятые", если тебе не говорили об этом в школе). Будешь продолжать писать, как сейчас, буду удалять твои посты.
Записан

Слово не воробей. Всё не воробей, кроме воробья.
Dmytry
Гость
« Ответ #14 : 26-11-2009 19:01 » 

Хорошо,без вопросов Да-да
Записан
Вад
Команда клуба

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

« Ответ #15 : 26-11-2009 19:09 » 

Dmytry, путанно пишешь. Не совсем понимаю, что происходит.
Твоя проблема - в том, что ты громоздишь всё в одну кучу, и уже сложно разобраться, откуда ползёт ошибка. Программирование - это, в том числе, структурирование задачи.
Возьми отдельно хэш-таблицу. Возьми пару пробных значений хэша и пару-тройку тестовых имён файлов. Попробуй добавить в хэш так, чтобы тестовые имена добавлялись для разных ключей. Потом для одного и того же ключа добавь два файла. Убедись, что всё организованно так, как задумано: пути хранятся в списках, списки хранятся в хэш-таблице, по одному экземпляру списка для одного ключа-хэша.

А уже потом прикручивай оттестированный код, который заведомо работает на тестовых данных, к основному коду. Попутно подумав, не стоит ли сделать как-нибудь так, чтобы этот оттестированный код как можно меньше соприкасался с окружающим кодом: ведь он решает свою отдельную задачу, и если его просто втыкать копипастом везде, где надо, в проекте будет каша.
Записан
Dmytry
Гость
« Ответ #16 : 26-11-2009 19:14 » 

Хорошо.Попробую Класс!
Записан
Dmytry
Гость
« Ответ #17 : 27-11-2009 14:31 » 

Я вот еще о чем думал (забегая немножко вперед): когда я, допустим, найду массив из моих дублированных файлов, то мне потом нужно будет выполнить следующее условие:
"- форма с перечнем найденных файлов, которые дублируются, с возможностью их открытия прямо из дополнения (например, двойным нажатием левой кнопки мыши);". Так вот, меня волнует, какого типа у меня должен будет быть массив из моих дубликатов, чтобы потом я смог, кликнув мишкой по любому файлу, открыть его (думаю, что он будет открываться с помощью блокнота). И как вообще это можно реализовать будет - открытие файла с помощью блокнота двойным щелчком мыши???
« Последнее редактирование: 27-11-2009 17:21 от Sel » Записан
Вад
Команда клуба

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

« Ответ #18 : 27-11-2009 15:11 » 

Чтобы открыть файл, нужен его полный путь. Чтобы открыть файл в блокноте, достаточно запустить блокнот с путём к файлу в качестве аргумента командной строки (например, "notepad C:\path_to_file\file.txt").
Для запуска внешних приложений есть масса способов. Например, есть WinAPI-функция ShellExecute - можно её импортировать в C#-код и использовать для запуска блокнота.
Записан
Dmytry
Гость
« Ответ #19 : 27-11-2009 15:52 » 

Спасибо! Теперь я еще лучше понимаю, зачем в хэш-таблице в паре "ключ-значение" значением должен быть путь к файлу Класс!
« Последнее редактирование: 27-11-2009 17:21 от Sel » Записан
Dmytry
Гость
« Ответ #20 : 28-11-2009 11:50 » 

Пробовал твой совет"Попробуй добавить в хэш так, чтобы тестовые имена добавлялись для разных ключей. Потом для одного и того же ключа добавь два файла. Убедись, что всё организованно так, как задумано: пути хранятся в списках, списки хранятся в хэш-таблице, по одному экземпляру списка для одного ключа-хэша." -не все так гладко как хотелось...добавь для одного и того же ключа д файла не получается и скорее всего не возможно...так как ключи должны быть уникальны ну и соотвецтвенно значения тоже.Не знаю , может это у меня руки дырявые, но все что получилось сделать - создать хеш-таблицу , заполнить ее так как ты сказал(пути хранятся в списках, списки хранятся в хэш-таблице, по одному экземпляру списка для одного ключа-хэша.) Жаль

Код:
//запис до хеш-таблиці//

            Hashtable myhash = new Hashtable();//створення хеш-таблиці
            for (j = 0; j < c; j++)
            {
                myhash[keyarray[j]]=pathpathtodir[j];//заповнення таблиці ключами і відповідними їм значеннями
                listBox1.Items.Add(myhash[keyarray[j]]);//вивід результату пошуку значешь за заданими ключами
               
            }
Записан
Вад
Команда клуба

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

« Ответ #21 : 28-11-2009 20:08 » 

Вот опять вперёд забегаешь. Что такое keyarray[j], что такое pathpathtodir[j]?
Когда я говорю "тестовые данные", я говорю вот о чём:
Код:
Hashtable myhash = new Hashtable();
// добавляем лист для ключа key1, если его ещё нет
if (!myhash.Contains("key1")){
    myhash.Add("key1", new ArrayList());
}
// добавляем значение пути в ключ
myhash["key1"].Add("C:\\file1.txt");

if (!myhash.Contains("key2"){  
    myhash.Add("key2", new ArrayList());
}
myhash["key2"].Add("C:\\file2.txt");
// и ещё один файл
myhash["key2"].Add("C:\\file3.txt");
и т.п. И вот когда "на пальцах" будет понятно, что всё работает как задумано (и что вообще понятно, как именно всё задумано) - тогда можно смело интегрировать этот код. Я вот пока не понимаю, откуда у тебя вдруг готовые списки берутся - по моей задумке, неоткуда им браться Улыбаюсь Их на месте создавать надо (что и отражает мой код)
« Последнее редактирование: 28-11-2009 20:21 от Вад » Записан
Dmytry
Гость
« Ответ #22 : 29-11-2009 06:02 » 

"Что такое keyarray[j], что такое pathpathtodir[j]?" - отвечаю. В keyarray[j], хранятся уже все хэши файлов в указанной мною директории, а в pathpathtodir[j] - пути к файлам, что принадлежат этим  хэшам.

Попробую немного объяснить ход своих мыслей: в начале нам не известно ни количество ключей, ни количество файлов, ни количествО дубликатов для заданного ключа. Я  ввожу путь к директории, выполняется поиск файлов в этой директории, и находится хэш каждого файла. Потом эти хэши складываются в массив keyarray[j] в том порядке, в котором были найдены файлы в каталоге. А  pathpathtodir[j] - это список путей к этим файлам, который был извлечен с помощью foreach из массива  files[j], который имеет тип fileInfo, потому только с помощью foreach можно извлечь пути к файлам из массива  files[j].

Я, вроде как, уловил ход твоих мыслей - Ты хочешь для каждого ключа создать свой список файлов, которые ему принадлежат. Твой пример это наглядно показывает. Но я все же не могу понять, как узнать, какие файлы добавлять к ключу, который им равен, то есть, то, что я и говорил - с начала не известно, какие файлы именно принадлежат ключу и сколько вообще этих ключей. Хотя твоя фраза "тогда можно смело интегрировать этот код" прольет свет и разгонит темные и густые облака  моих раздумий и гаданий. 
« Последнее редактирование: 29-11-2009 07:27 от Sel » Записан
Вад
Команда клуба

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

« Ответ #23 : 29-11-2009 10:24 » 

"Что такое keyarray[j], что такое pathpathtodir[j]?" - отвечаю. В keyarray[j], хранятся уже все хэши файлов в указанной мною директории, а в pathpathtodir[j] - пути к файлам, что принадлежат этим  хэшам.
Ты отвечаешь на вопрос, что в нём хранится, а не что такое pathpathtodir Улыбаюсь Это тоже нужная информация, но не вся. Нужна ещё важная информация:  какой тип имеет элемент списка pathpathtodir?
Допустим, что pathpathtodir представляет собой список списков путей. А список ключей-хэшей к нему хранится отдельно (в keyarray). Но в таком случае это дублирует подход, который я предлагал, просто вместо одного объекта (Hashtable) используется два (список ключей и список списков), и хэши хранятся просто в порядке поступления.

Цитата
Но я все же не могу понять, как узнать, какие файлы добавлять к ключу, который им равен, то есть, то, что я и говорил - с начала не известно, какие файлы именно принадлежат ключу и сколько вообще этих ключей.
Всё предельно просто. Сначала имеем пустой хэш. В этот момент мы ещё не начали вычислять хэши для содержимого файлов.
Затем приступаем к вычислению хэшей для файлов и сразу, непосредственно добавляем пути файлов в хэш-таблицу. Для этого нужно выполнить следующие действия:
1. Проверить, существует ли уже запись в таблице для текущего хэша (myhash.Contains(<ключ>))
2. Если ключа в таблице нет - это означает, что ранее для такого ключа значений не добавляли, и нужно создать пару "ключ-значение" для дальнейшего хранения списков:
myhash.Add(<ключ>, new ArrayList());
3. Добавить значение (путь к файлу) к списку путей для данного ключа:
myhash[<ключ>].Add(<путь>);

Вот и всё. Не надо узнавать, какие файлы добавлять к ключу: ты уже знаешь ключ для данного файла, и тебе всего лишь нужно добавить путь в таблицу по ключу, убедившись предварительно, что для данного ключа создан список путей.
« Последнее редактирование: 29-11-2009 10:27 от Вад » Записан
Dmytry
Гость
« Ответ #24 : 29-11-2009 10:32 » 

Цитата
"Ты отвечаешь на вопрос, что в нём хранится, а не что такое pathpathtodir
Это тоже нужная информация, но не вся. Нужна ещё важная информация:  какой тип имеет элемент списка pathpathtodir?" - как ты понял, это список списков путей. Тип у него string.

Насчет "Затем приступаем к вычислению хэшей для файлов и сразу, непосредственно добавляем пути файлов в хэш-таблицу." - у меня алгоритм вычисления хэша работает только для строки. C массивом не работает(насколько я понял). Я с помощью foreach брал из массива files[j] типа fileInfo имена файлов, читал их и сразу же находил их хэш. То есть, в результате у меня в переменной hash2 string хранятся  хэши этих файлов. Потом я добавлял их в список fileHashes типа string для того, чтоб получить контроль над каждым хэшем (кстати, keyarray -это просто копия списка fileHashes типа string[])
« Последнее редактирование: 29-11-2009 14:24 от Sel » Записан
Вад
Команда клуба

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

« Ответ #25 : 29-11-2009 10:58 » 

Правильно. Хэши считаются по одному.
Берём файл. Считаем хэш. Затем, если пользоваться хэш-таблицей, кладём имя файла в нужное место в хэш-таблице. По одному. Зачем тут какой-то массив?

Ведь ты же, когда группируешь файлы по хэшам в своём pathpathtodir - ты ведь всё равно как-то ищешь, в какой список тебе нужно положить файл? (иначе зачем нужны списки) А хэштаблица просто делает поиск проще и быстрее.
Записан
Dmytry
Гость
« Ответ #26 : 29-11-2009 11:06 » 

Так вроде понял сейчас буду корректировать и потом выложу код.Спасибо за разъяснение!! 
Записан
Dmytry
Гость
« Ответ #27 : 29-11-2009 11:29 » 

Вот отредактировал и постарался сделать как можно больше разъяснений, что б тебе было ясно:
Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.IO;
using System.Collections;
namespace kursovoy
{
    
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        static string getMd5Hash(string input)
        {
            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 md5Hasher = MD5.Create();

            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

            // Create a new Stringbuilder to collect the bytes
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data
            // and format each one as a hexadecimal string.
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string.
            return sBuilder.ToString();
        }

        // Verify a hash against a string.
        static bool verifyMd5Hash(string input, string hash)
        {
            // Hash the input.
            string hashOfInput = getMd5Hash(input);

            // Create a StringComparer an comare the hashes.
            StringComparer comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        
        private void button1_Click(object sender, EventArgs e)
        {

            listBox1.Items.Clear();
            listBox2.Items.Clear();
            //Объявление переменных
            
            
            string hash2;//объявление переменой ч тобудет хранить хэши
            List<string> fileHashes = new List<string>();//переменная списка хешей
            List<string> pathpathtodir = new List<string>();//переменная списка путей(по твоей рекомендации пока не использовал)
            
            
            
            // Каталог для створення файлів проекту
            string ProjDir = textBox1.Text;

            //Отображение файлов в каталоге
            string searchPattern = "*.txt";

            DirectoryInfo di = new DirectoryInfo(@ProjDir);
            DirectoryInfo[] directories =
            di.GetDirectories("*", SearchOption.AllDirectories);

            FileInfo[] files =
                di.GetFiles(searchPattern, SearchOption.AllDirectories);
            
            //об`ява змінних та визначення довжини масивів файлів та директорій
            
            int j;//переменная для работы с масивами
            int c = files.Length;//количество файлов
            int d = directories.Length;//количество директорий

            //занесення шляхів директорій у список pathtodir
            foreach (DirectoryInfo dir in directories)
            {
                pathpathtodir.Add(dir.FullName);//заношу пути в список путей(на будущее , вдруг понадобится)
            }
            //Читання масиву файлів та знаходження хешів цих файлів і додавання його у новій список 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);// это заносил в список хеэши , но по твое рекомендации ее не применял а только использовал для проверки работы вычисления хэша


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

            }
            //відображення кількості файлів та підкаталогів у заданому користувачем каталозі
            listBox3.Items.Add(c);//вывод кроличества файлов
            listBox4.Items.Add(d);//вывод количества каталогов в заданой мною директории
            for (j=0;j<c;j++)
            {
            listBox1.Items.Add(fileHashes[j]);//вывод списка хэшей тольк одля проверки работы нахождения хэша
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
                
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void listBox2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void listBox3_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void listBox4_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void listBox5_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
}
}



« Последнее редактирование: 29-11-2009 11:32 от Dmytry » Записан
Dmytry
Гость
« Ответ #28 : 29-11-2009 12:05 » 

Вроде сделал все ка ты сказал...откомпилировал и получил по сути то что до этого тоже получалось - список неупорядоченный путей к файлам. Вывод : либо это еще только вершина айсберга и дальше нудно еще что то сделать что б при сортировании ключей выводились отсортированные пути, либо - у меня руки вообще из не того места растут и я вывожу в форму ну совсем не то что нужно:( (нужно сгруппированные пути к файлам, то есть что бы дубликаты выводились рядом один с одним)
« Последнее редактирование: 29-11-2009 12:11 от Dmytry » Записан
Вад
Команда клуба

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

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

Чтобы дубликаты выводились рядом, нужно всего лишь отделить сбор информации от её вывода.
То есть, сначала в отдельном цикле заносить результат в хэш-таблицу. А затем в другом цикле выводить содержимое этой таблицы. (заодно можно будет, например, вставлять какие-нибудь разделители между элементами, чтобы было видно, какие именно файлы принадлежат к одной группе дубликатов).
Второй цикл будет чем-то вроде
Код:
foreach(DictionaryEntry d in myhash)
{
// Заносим все элементы из списка d.Value в ListBox
}
вот тогда всё будет сгруппировано
Записан
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 » Записан
Вад
Команда клуба

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

« Ответ #60 : 01-12-2009 18:57 » 

Да, я про этот ListView. У него функциональность намного шире, чем у ListBox. В чистом WinAPI есть способы хранить в нём дополнительные данные (помимо собственно выводимого текста, хранить в элементах и другие данные) - здесь тоже должны быть.
Записан
Dmytry
Гость
« Ответ #61 : 01-12-2009 19:29 » 

Я пробовал с ним разобраться - кое что выходит. Но здесь ,я так понял,  чем то похожим на  ListBox.Item.Add() - ничего не выведешь...нужно создавать этот ListView, потом устанавливать его параметры, задавать переменные и потом в них выводить нужные нам списки. Я поgробую дальше разобраться, но что то я, если честно, не могу понять, как тогда поступать с выводом и что хранить в списках Hashtable - пути к файлу и все же весь файл целиком(с параметрами имени и пути к нему)?. И какого он тогда типа будет вообще?
Записан
Sla
Команда клуба

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

WWW
« Ответ #62 : 01-12-2009 20:09 » 

Dmytry, на мой взгляд, ты усложняешь себе задачу.

ты строишь массив  хешей, и запихиваешь их в list. Зачем?
работа со списками сложнее чем с  массивами.


2 Вад. списки это красиво, но не понимаю в условиях этой задачи.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #63 : 01-12-2009 20:49 » 

Слав, у него заранее не известно количество элементов в массиве. Поэтому использование списков вполне оправдано. Хотя он пишет на шарпе, там не так актуален вопрос расширяемости массивов, насколько я помню.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Sla
Команда клуба

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

WWW
« Ответ #64 : 01-12-2009 21:04 » 

Finch, тут какая штука.

Я не люблю, с очень давних пор,  вообще понятия  указателей, т.е. кучи.
Почему? разговор отдельный.
Потому и  появление шарпа приветствую, потому как он не подразумевает обращения напрямую к "куче".
Но с другой стороны понятие указатель-куча-список, это святое, это классика.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #65 : 01-12-2009 21:18 » 

Слав, топик полностью не читал. Но std::list как контейнер вполне позволяет забыть про указатели-кучу в С++. Насколько я знаю в шарпе со вторым дот нетом есть генерические контейнеры. Которые имеют такой же принцип работы, как list.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Dmytry
Гость
« Ответ #66 : 02-12-2009 05:31 » 

Спасибо за советы. Так как мне лучше поступить?Вад предлагает мне выводить результаты поиска в ListView. Я с ним в этом согласен потому что, во-первых, насколько я понял, LisBox, что я сейчас использую для вывода результатов, выводит только те данные, которые я запросил, но не может нести какую-то дополнительную информацию в выводимом элементе. А во-вторых, там есть такой элемент как галочки, что мне, думаю, понадобится при решении последней задачи - выбора дубликатов из списка и упаковывания их с помощью J-ZIP. Задача сейчас у меня стоит следующая - у меня сейчас выводится список имен файлов дубликатов в LisBox, мне нужно реализовать открытие любого из этих файлов на чтение. Я подумал, что самым лучшим вариантом было бы открывать файлы с помощью блокнота. Я нашел  Process - класс, который, как я думаю, поможет мне реализовать открытие файла с помощью приложения. Но есть некоторые нюансы. Мне, чтоб воспользоваться одним из методов этого класса, нужно знать как имя файла, так и полный путь к нему. В программе у меня выводится только одна из этих оставляющих - либо путь, либо имена файлов (у меня по условию задания должны выводиться имена файлов). Вот Вад и подсказал мне, что в таком случае лучше пользоваться  ListView. Может, у кого-то есть другие варианты решения поставленной проблемы?? Поделитесь, пожалуйста.
« Последнее редактирование: 02-12-2009 05:55 от Sel » Записан
Вад
Команда клуба

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

« Ответ #67 : 02-12-2009 06:18 » 

2 Вад. списки это красиво, но не понимаю в условиях этой задачи.
В данном случае, списки - это удобная динамическая структура, для которой не надо думать о её размере. А размер списка дубликатов заранее неизвестен.

Слав, топик полностью не читал. Но std::list как контейнер вполне позволяет забыть про указатели-кучу в С++. Насколько я знаю в шарпе со вторым дот нетом есть генерические контейнеры. Которые имеют такой же принцип работы, как list.
Есть, но ещё и про generic-и объяснять - это уже, на самом деле, красиво, но я не берусь Улыбаюсь Пару намёков на них я, впрочем, давал Улыбаюсь
« Последнее редактирование: 02-12-2009 06:21 от Вад » Записан
Вад
Команда клуба

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

« Ответ #68 : 02-12-2009 06:27 » 

Dmytry, предложения, высказанные выше, относятся не к ListView, а к организации хранения значений в процессе вычисления хэшей для файлов.
Так что это не должно тебя отвлекать от поиска способа отобразить список файлов Улыбаюсь

Кстати, когда ты говоришь
Цитата
Мне, чтоб воспользоваться одним из методов этого класса, нужно знать как имя файла, так и полный путь к нему. В программе у меня выводится только одна из этих оставляющих - либо путь, либо имена файлов (у меня по условию задания должны выводиться имена файлов)
- ты что имеешь в виду под путём к файлу? Я подразумеваю полный путь, включая имя: "C:\temp\1\file.txt".
Чтобы отобразить только имя, необязательно его хранить всё время: в C# должны быть функции для манипуляции с именами файлов (в т.ч. и выделения имени из полного пути) - в крайнем случае, можно стандартными средствами отрезать. Хотя если тебе так удобнее - можно и хранить пару значений.
Записан
Sel
Злобный
Администратор

ru
Offline Offline

« Ответ #69 : 02-12-2009 11:14 » 

Dmytry, исправь ошибки в своем сообщении и опубликуй заново. Предупреждала сто раз, чтобы писАл грамотно. Безграмотные сообщения отныне удаляются.
Записан

Слово не воробей. Всё не воробей, кроме воробья.
Dmytry
Гость
« Ответ #70 : 02-12-2009 11:27 » 

Вот снимок экрана при запуске моей программы:
http://files.mail.ru/VL76NB

Как ты видишь, в первой колонке дубликаты отображаются в виде неполных путей - то есть, путь указан без названия файла. Это значит, что я что-то не так вывожу? Потому как я подозреваю, что эти пути в таком виде и записываются в список Hashtable. Насчет обрезания выводимой части файла - насколько я тебя понял, listBox может сгодитЬся, если будет доступен полный путь к файлу и как-то можно будет вырезать при выводе только имя файла (либо специальными функциями, либо стандартным способом, под которым, я думаю, будет работа с простыми кавычками), или все же ты мне посоветуешь дальше мучить ListView, так как он будет лучше подходить для выполнения 2 поставленных задач: открытие файла, приоритет которого выше, и архивация выделенных файлов в J-Zip??
« Последнее редактирование: 02-12-2009 11:38 от Sel » Записан
Вад
Команда клуба

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

« Ответ #71 : 02-12-2009 12:35 » 

Цитата
Потому как я подозреваю, что эти пути в таком виде и записываются в список Hashtable
Так поставь брейкпойнт и погляди, что именно записывается в Hashtable. В принципе, ты же ведь файл открываешь на чтение по имени, чтобы хэш посчитать - значит, должен быть полный путь до файла, с именем.

Кстати, вырезать имя я считаю не очень хорошей идеей - на самом деле, они же одноимённые могут быть. Поэтому лучше выводить прямо полный путь, чтобы пользователь сразу видел, где какой дубликат лежит (возможны и другие решения, но это кажется мне пока более удачным). Тогда, в принципе, даже дополнительные фичи ListView не нужны. А основные - очень простые: нужно только поставить списковый стиль (что-то типа report) и чек-боксы, которые тебе нужны, включить.
Записан
Dmytry
Гость
« Ответ #72 : 02-12-2009 15:54 » 

По поводу брейкпойнта - признаюсь - не знаю как его поставить, но вот что я скажу по поводу полного пути. У меня функция чтения имеет два параметра: путь к файлу(без имени самого файла) и имя файла. Вот код:
Код:
string nameFile = file.Name;// переменная хранящая имя фалйов
                string pathoffile = file.DirectoryName;//переменная хранящая пути к файлам            
                // Шлях до файлу
                string pathFile = System.IO.Path.Combine(pathoffile, nameFile);
                // Читання файлу
                string contents2 = System.IO.File.ReadAllText(pathFile);
                


Я здесь подумал и вспомнил одно дело. Если у нас переменная, что отвечает за конечный результат, носит тип string, то можно ведь попробовать как-то склеить имя файла и путь. Вот например что-то типа такого:
Код:
// добавляем значение пути в ключ
                ((ArrayList)myhash[hash2]).Add(file.DirectoryName+file.Name);

Только нужно как-то правильно эту запись сформировать, чтоб был еще в строке списка "\".Как тебе такой вариант? Такое возможно?

 
 
 
« Последнее редактирование: 02-12-2009 16:02 от Dmytry » Записан
Dmytry
Гость
« Ответ #73 : 02-12-2009 16:54 » 

Пытаюсь разобраться с ListView. Выходит не очень Здесь была моя ладья...
Вот пример:
Код:
private void CreateMyListView()
        {// Set the view to show details.
            listView1.View = View.Details;//Это ,как я понял ,включение режима для работы всех остальных настроек
            // Allow the user to edit item text.
            listView1.LabelEdit = false;// Это ,насколько я понял, для редактирования имени файлов прямо из формы. Потому отключил его
            // Allow the user to rearrange columns.
            listView1.AllowColumnReorder = true;
            // Display check boxes.
            listView1.CheckBoxes = true;// Это ,как я понял, те боксы о которых ты говорил
            // Select the item and subitems when selection is made.
            listView1.FullRowSelect = true;// Вот это, толком не могу понять, что имеется ввиду?
            // Display grid lines.
            listView1.GridLines = false;//Это ,как я понял, линии сетки ,чтоб было похоже на таблицу
            // Sort the items in the list in ascending order.
            listView1.Sorting = SortOrder.Ascending;// Это , как я понял, сортировка. Она нужна вообще??
            ListViewItem item1 = new ListViewItem();// Вот здесь тоже немного не пойму.Это получается объявление переменной, что отвечает
за вывод?          
            item1.Checked = true;// Вот это тоже для меня загадка :(
            item1.SubItems.Add("1");// Как я понял, это и есть то, что мне нужно - занесение данных в переменную.
            item1.SubItems.Add("2");
            item1.SubItems.Add("3");
            listView1.Columns.Add("Item Column", -2, HorizontalAlignment.Left);// Вот эти параметры немного смущают меня. Я так понял, здесь указывается, как будут отображаться все данные в listView

            listView1.Columns.Add("Column 2", -2, HorizontalAlignment.Center);
            listView1.Columns.Add("Column 3", -2, HorizontalAlignment.Center);
            listView1.Columns.Add("Column 4", -2, HorizontalAlignment.Center);
            listView1.Items.AddRange(new ListViewItem[] { item1 });// А это, как я понял, вывод в listView всех данных
            // Add the ListView to the control collection.
            this.Controls.Add(listView1);// Не могу понять нужен ли этот параметр? Если дословно перевести, то это добавление коллекции контроля?

Вот, что я понял насчет listView. Мне нужно создать listView, установить его параметры , создать переменную item и потом с помощью item1.SubItems.Add() забивать данные в переменную  item,  а с помощью   listView1.Items.AddRange(new ListViewItem[] { item1 }) выводить все в форму, так?

По поводу стилей (что-то типа report). Я нашел что-то похожее. Называется ListView.HeaderStyle -  возвращает или задает стиль заголовка столбца. Это то, о чем ты говорил?  
« Последнее редактирование: 02-12-2009 16:57 от Dmytry » Записан
Вад
Команда клуба

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

« Ответ #74 : 02-12-2009 21:45 » 

Цитата
По поводу брейкпойнта - признаюсь - не знаю как его поставить
Плохо Улыбаюсь Отладчик в целом и точки останова в частности - наиполезнейшая штука, особенно если нужно разобраться, что именно в программе происходит, и что в ней идёт не так, как задумано. Так что настоятельно рекомендую изучить.

Цитата
Код:
string pathFile = System.IO.Path.Combine(pathoffile, nameFile);
Полагаю, это именно то, что нужно.

С ListView всё немного попроще. Код примера предполагает, что свойства выставляются вручную. На самом деле, есть ещё один способ проставить свойства списка - сделать это в редакторе формы. Там должна быть закладка со свойствами объекта: когда помещаешь ListView на форму, можно отредактировать свойства и посмотреть. Стиль, о котором я говорил, кажется, называется в C# "details view". Дома нет студии, чтоб посмотреть точно.

Насчёт добавления - ты перегнул, диапазон из одного элемента добавлять ни к чему Улыбаюсь Проще тогда  уж сделать listView1.Items.Add(item1);
В любом случае, для каждой строки нужно создавать отдельный элемент. Это нужно делать в цикле. В общем, смотри примеры, пробуй их - на то они и даны, понимай, как оно работает, и применяй к своему случаю
Записан
Dmytry
Гость
« Ответ #75 : 03-12-2009 05:12 » 

Цитата
Полагаю, это именно то, что нужно.
Насколько я тебя понял, ты предлагаешь в Hashtable хранить переменную string pathFile из
Код:
string pathFile = System.IO.Path.Combine(pathoffile, nameFile);
?
Записан
Вад
Команда клуба

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

« Ответ #76 : 03-12-2009 13:56 » 

Да, и я это имел в виду с самого начала Улыбаюсь
Записан
Dmytry
Гость
« Ответ #77 : 03-12-2009 17:28 » 

По твоему совету начал разбираться и вот что вышло. Ты говорил ,чтоб я поставил "details view", я нашел этот параметр, поставил его и начал компилировать - тупо пустой ListView! Поставил параметром List - заработало. Поставил еще чек-боксы - вот что вышло(центральная колонка):
http://files.mail.ru/0VIXAI

Вот код того ,что я сделал, чтоб так выводило:
Код:
listView1.CheckBoxes = true;
foreach (DictionaryEntry val in myhash)
            {
                ArrayList lst = (ArrayList)(val.Value);
                if (lst.Count > 1)
                {
                    // Заносим все элементы из списка d.Value в ListBox
                    foreach (string pathToFile in (ArrayList)val.Value)
                    {
                        listView1.Items.Add(pathToFile); //Вывод путей для ключей           
                    }
                }
            }


Но вот у меня появилась маленькая проблема - я не знаю, как отделить дубликаты. В варианте с ListBox, я просто писал строку перед условием:
Код:
listBox1.Items.Add("--ГРУППА ДУБЛИКАТОВ--");


здесь такое не проходит Жаль. Ты не знаешь, как в таком случаи поступить?
Записан
Вад
Команда клуба

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

« Ответ #78 : 03-12-2009 20:49 » 

Сортировку убрать нужно. Тогда элементы будут в том порядке, в котором добавлялись.
Записан
Dmytry
Гость
« Ответ #79 : 04-12-2009 05:43 » 

Вад, спасибо огромное за совет - помогло Класс!
Я вчера, пока ждал твоего совета, занялся разработкой функции открытия файлов. По твоему совету использовал класс Process. Потом взял из примера и создал класс, добавил оттуда следующую функцию:
Код:
class MyProcess
        {
public void OpenWithArguments(string pathprocess)
            {
                Process.Start(pathprocess);
            }
        }


Потом объявил общедоступную переменную:
Код:
string ResultPath;//зберігає кінцевий масив із повних шляхів

Присвоил ей значение массива строк pathToFile в цикле
Код:
foreach (DictionaryEntry val in myhash)
:
Код:
ResultPath = pathToFile;

После этого создал кнопку в форме и записал в нее следующий код:
Код:
private void button2_Click(object sender, EventArgs e)
        {
           
            MyProcess myProcess = new MyProcess();//
            myProcess.OpenWithArguments(ResultPath);

Поробовал при компиляции - открывает, но есть 2 проблемы:
1) Насколько я понял, в ResultPath хранятся все полные пути и доступ к ним можно получить только через цикл. Попробовал создать цикл и вывести все элементы - не получилось. Выдало ошибку - что-то типа того ,что не может перевести с типа char  в string. вот код:
Код:
foreach (string fullpath in ResultPath)
                    {
                        listBox5.Items.Add(fullpath);
            }
2) Не могу понять, как привязать выбор открывающегося файла через чек-боксы. Нашел 2 свойства в ListView:
http://msdn.microsoft.com/ru-ru/library/system.windows.forms.listview.itemcheck.aspx
http://msdn.microsoft.com/ru-ru/library/system.windows.forms.listview.checkeditems.aspx

Не могу понять, какое из них мне нужно Жаль. А может есть еще какой-то способ отслеживать чек-боксы??
Записан
Вад
Команда клуба

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

« Ответ #80 : 04-12-2009 05:54 » 

Опиши, при каких именно действиях должно происходить открытие файлов в блокноте - и каких именно файлов.
BTW, в примере для CheckedItems есть подсказка - обработчик события ItemChecked. Вот с применением обработчиков событий списка и можно отслеживать действия - хоть выделение, хоть клик, хоть любое другое доступное.
Записан
Dmytry
Гость
« Ответ #81 : 04-12-2009 12:04 » 

Открытие файла в блокноте должно выполняться при таких действиях:
1) Ставлю галочку напротив тех файлов ,что хочу открыть(будь это 1,2 или все файлы целиком)
2) У меня есть созданная кнопка "Открыть", когда уже отметил галочками файлы, те, что хочу открыть - нажимаю на эту кнопку
3) В результате начинают открываться те файлы ,что я их отметил галочками , с помощью блокнота
Записан
Вад
Команда клуба

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

« Ответ #82 : 04-12-2009 13:31 » 

Тогда по нажатию кнопки получать список CheckedItems у ListView, выдёргивать оттуда (у item-ов) пути к файлам и открывать блокнотом, в цикле.
Записан
Dmytry
Гость
« Ответ #83 : 04-12-2009 14:56 » 

Спасибо за алгоритм. Буду пробовать.
« Последнее редактирование: 04-12-2009 15:56 от Dmytry » Записан
Dmytry
Гость
« Ответ #84 : 05-12-2009 07:11 » 

Никак не могу понять, как получить список CheckedItems у ListView Жаль Жаль Жаль
Код:
private void listView1_check2(object sender,
        System.Windows.Forms.ItemCheckEventArgs e)
        {
            ListView.CheckedListViewItemCollection checkedItems =
               listView1.CheckedItems;// Насколько я понял, здесь создается коллекция  CheckedItems , в которой будут хранится отмеченные элементы

            foreach (ListViewItem item in checkedItems)
            {
                if (e.CurrentValue == CheckState.Checked)// Здесь,как я понял, выполняется проверка на то ,стоит ли галочка или нет
                {
                    listBox5.Items.Add("proba");//Это я пробовал при выполнении условия для начала просто вывести надпись в  listBox5   
                }
            }
        }

И ничего не получается Жаль
Записан
Dmytry
Гость
« Ответ #85 : 05-12-2009 08:06 » 

УРА! Все получилось. Если честно, даже не ожидал, что все будет так просто:
Код:
private void button2_Click(object sender, EventArgs e)
        {
                MyProcess myProcess = new MyProcess();
                ListView.CheckedListViewItemCollection checkedItems =
                listView1.CheckedItems;
                foreach (ListViewItem item in checkedItems)
                {
                    myProcess.OpenWithArguments(item.Text);
                }

    }

Теперь перехожу к последней задаче - упаковка выбранных файлов в архив GZIP. Вот, вроде как, нашел материал по нему:
http://msdn.microsoft.com/ru-ru/library/system.io.compression.gzipstream.aspx

Планирую выполнять такие действия:
1) отмечаю галочками файлы для упаковки
2) У меня будет создана кнопка "Упаковать в GZIP архив"
3) при ее нажатии файлы упаковываются и, скорее всего, архив будет лежать в той папке, что задавалась с самого начала мной при поиске дубликатов

Сразу появился вопрос:
Как лучше сделать? Не давать пользователю возможности предварительного просмотра выбранных для упаковки файлов, или все же перед самой упаковкой выводить список из них в какое-то дополнительное поле??
« Последнее редактирование: 05-12-2009 08:28 от Sel » Записан
Страниц: 1 2 3 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines