Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
 Аватар для артист
50 / 35 / 21
Регистрация: 17.09.2014
Сообщений: 1,611

Поиск одинаковых файлов в папке и перенос копий в другую папку (оптимизация кода)

19.12.2015, 13:42. Показов 2514. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Программа ищет одинаковые файлы в папке где сама находится(по маске или расширению), по хэшу, и перемещает все копии в отдельную папку.

Так - то всё работает, но мне кажется использование функций из разных языков неправильно...

Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <windows.h>
#include <iostream>
#include <string>
#include <map>
 
#define BUFSIZE 1024
#define MD5LEN  16
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    WIN32_FIND_DATA winFileData;
    DWORD dwStatus = 0;
    DWORD cbRead = 0;
    DWORD cbHash = 0;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;
    HANDLE dFile = NULL;
    HANDLE hFile = NULL;
    BOOL bResult = FALSE;
    BYTE rgbFile[BUFSIZE];
    BYTE rgbHash[MD5LEN];
    CHAR rgbDigits[] = "0123456789abcdef";
    CHAR md5str[MD5LEN * 2 + 1] = "\0";
    INT allfiles = 0, copies = 0;
    WCHAR szPath[MAX_PATH], exp[10];
    WCHAR szPathM[MAX_PATH];
    WCHAR szPathTo[MAX_PATH] = L"Копии";
    int i = 0;
 
    std::multimap <std::string, std::wstring> md5filename;
 
    if(!GetCurrentDirectoryW(sizeof(szPath), szPath)) 
    {
        std::cout << L"Невозможно получить текущую папку" << std::endl;
        system("pause");
        return 0;
    }
    std::wcout << L"Текущая папка : " << szPath << L'\\' << std::endl << std::endl << L"Введите расширение файлов : ";
 
    lstrcat(szPath, L"\\*.");
 
    std::wcin >> exp;
 
    lstrcat(szPath, exp);
 
    std::wcout << std::endl;
 
    if((dFile = FindFirstFile(szPath, &winFileData)) == INVALID_HANDLE_VALUE)
    {
        std::cout << L"Нет файлов в папке" << std::endl << std::endl;
        system("pause");
        return 0;
    }
    while (!CreateDirectory(szPathTo, NULL)) wsprintf(szPathTo, L"Копии (%i)", ++i); // Создать папку для копий
    
 
    do // Цикл по файлам
    {
        if(winFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; // Если это не файл - тогда дальше
 
        hFile = CreateFile(winFileData.cFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
 
        if(hFile == INVALID_HANDLE_VALUE) // Попытка открыть файл для чтения 
        {
            std::wcout << L"Невозможно открыть файл " << winFileData.cFileName << std::endl;
            continue;
        }
        if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        {
            dwStatus = GetLastError();
            std::wcout << std::endl << L"Ошибка, не удалось получить контекст: " << dwStatus << std::endl << std::endl;
            CloseHandle(hFile);
            continue;
        }
        if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
        {
            dwStatus = GetLastError();
            std::wcout << std::endl << L"Ошибка, не удалось получить контекст: " << dwStatus << std::endl << std::endl;
            CloseHandle(hFile);
            CryptReleaseContext(hProv, 0);
            continue;
        }
        while(bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))
        {
            if(cbRead == 0) break;
 
            if(!CryptHashData(hHash, rgbFile, cbRead, 0))
            {
                dwStatus = GetLastError();
                std::wcout << std::endl << L"Ошибка, не удалось получить хэш: " << dwStatus << std::endl << std::endl;
                CryptReleaseContext(hProv, 0);
                CryptDestroyHash(hHash);
                CloseHandle(hFile);
                continue;
            }
        }
        if(!bResult)
        {
            dwStatus = GetLastError();
            std::wcout << std::endl << L"Ошибка, не удалось прочитать файл: " << dwStatus << std::endl << std::endl;
            CryptReleaseContext(hProv, 0);
            CryptDestroyHash(hHash);
            CloseHandle(hFile);
            continue;
        }
        cbHash = MD5LEN;
 
        if(CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
        {
 
            for(int j = 0, i = 0; i < cbHash; i++)
            {
                md5str[j++] = rgbDigits[rgbHash[i] >> 4];
                md5str[j++] = rgbDigits[rgbHash[i] & 0xf];
            }
            md5filename.insert(std::pair<std::string, std::wstring>((std::string)md5str, (std::wstring)winFileData.cFileName));
            allfiles++;
        }
        else
        {
            dwStatus = GetLastError();
            std::wcout << std::endl << L"Ошибка, не удалось получить параметры : " << dwStatus << std::endl << std::endl;
        }
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        CloseHandle(hFile);
    }
    while(FindNextFile(dFile, &winFileData));
 
    std::wcout << std::endl << std::endl << "-----------------------------------------------------" << std::endl;
 
    std::string previos, first; // Для хранения предыдущего и текущего хэша
    std::wstring pname, fname;  // Для хранения предыдущего и текущего имёни файла
 
    for(auto it = md5filename.begin(); it != md5filename.end(); it++) // Вывод одинаковых файлов
    {
        first = it->first;          // Запись текущего хэша
 
        if (first == previos)       // Если текущий хэш равен предыдущему
        {
            fname = it->second;     // Получить имя файла (текущее)
            std::wcout << fname << std::endl;   // Вывести имя файла
 
            wsprintfW(szPathM, L"%s\\%s", szPathTo, fname.c_str()); // Форматирование нового пути файла
            MoveFileEx(fname.c_str(), szPathM, MOVEFILE_REPLACE_EXISTING);  // Переместить копию в папку копий
 
            copies++;               // Посчитать копию
        }
        else                        // Если хэш не равен предыдущему
        {
            previos = first;        // Записать новый хеш
            pname = it->second;     // Получить имя файла (предыдущее)
 
            std::cout << std::endl << first;
            std::wcout << L" : Копий - " << md5filename.count(first) << std::endl; // Вывести хеш и число копий
            std::wcout << pname << std::endl; // Вывести имя файла
        }
    }
    std::wcout << std::endl << std::endl << L"Всего найдено файлов - " << allfiles << L" Найдено копий - "<< copies << std::endl << std::endl;
 
    if(!copies) RemoveDirectory(szPathTo);
    system("pause");
    return 0;
}


Кто может подсказать, сколько тут их и на каком предпочтительнее?
Просто я совсем не понимаю где есть что...

Вот например, std::multimap - сортировка без него невозможна(замена на циклы с чарами не особо хочется + безразмерный массив не знаю как делать)

Вот на каком это языке?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.12.2015, 13:42
Ответы с готовыми решениями:

Поиск и перенос файлов *.jpeg *.png *.jpg в другую папку
Get-ChildItem e:\img -Recurse -include *png,*jpg,*bmp,*jpeg После этого находит все файлы с указанным расширением в папке, но не могу...

Поиск чисел в файлах в папке и копирование найденных в другую папку
Добрый день есть вопросик,есть папка в ней много файлов, в которых есть такая часть кода data-time=&quot;числа&quot;&gt;3...

Поиск копий файлов и удаление найденных копий
Столкнулся с подобным заданием и никак, не могу понять как его решить: Разработать пакетный файл, находящий копии файлов в 2х заданных...

6
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.12.2015, 15:22
Лучший ответ Сообщение было отмечено артист как решение

Решение

Что ты вкладываешь в понятие "язык"? Это С++. Если бы ты добавил сюда Паскаль или что-то ещё, она бы просто не скомпилировалась.
1
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
19.12.2015, 15:42
Лучший ответ Сообщение было отмечено артист как решение

Решение

Цитата Сообщение от артист Посмотреть сообщение
Вот например, std::multimap - сортировка без него невозможна
Просто ты не умеешь сортировать. Multimap - это реализация структуры данных, эквивалентен map, но в нем можно сопоставлять одному и тому же ключу разные значения.
Раз ты используешь multimap, то олжен предполагать, что у разных файлов может быть одинаковый хеш.
А раз так, то после сравнения хешей нужно еще и сравнить сами файлы, чтобы убедиться в том, что они совпадают.
1
 Аватар для артист
50 / 35 / 21
Регистрация: 17.09.2014
Сообщений: 1,611
19.12.2015, 17:07  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
Что ты вкладываешь в понятие "язык"? Это С++. Если бы ты добавил сюда Паскаль или что-то ещё, она бы просто не скомпилировалась.
Ну может не язык, а реализация, не знаю как называется...

Ну вот например FindFirstFile - это вин апи?
А string, map, cout - нет...

Цитата Сообщение от nonedark2008 Посмотреть сообщение
Просто ты не умеешь сортировать. Multimap - это реализация структуры данных, эквивалентен map, но в нем можно сопоставлять одному и тому же ключу разные значения.
Раз ты используешь multimap, то должен предполагать, что у разных файлов может быть одинаковый хэш.
А раз так, то после сравнения хэша нужно еще и сравнить сами файлы, чтобы убедиться в том, что они совпадают.
Сортировка мне бы и не была нужна, чтобы найти одинаковые строки достаточно проверять на сходство все последующие...
Я знаю что такое multimap, поэтому его и выбрал...
Ну это я не учёл...Достаточно будет просто сравнить размер файлов или crc хешэм, каким - нибудь...
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.12.2015, 17:24
Лучший ответ Сообщение было отмечено артист как решение

Решение

Использовать WinAPI и STL допустимо. Или ты хочешь всё вручную программировать?
1
 Аватар для артист
50 / 35 / 21
Регистрация: 17.09.2014
Сообщений: 1,611
19.12.2015, 17:32  [ТС]
Ааа... Да кто - то мне где - то сказал, что намешано у меня, если пишешь на вин апи(С++) то и пиши...
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
19.12.2015, 17:40
Ну может строки имелись в виду. В WinAPI нет контейнеров, так что заменить их нечем.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.12.2015, 17:40
Помогаю со студенческими работами здесь

Поиск файлов с одинаковыми символами в имени и перенос их в отдельную папку
здравствуйте форумчане. появилась такая проблемка: есть программа которая записывает телефонные звонки (формат .wav) и помещает их в одну...

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

Перенос Wordpress в другую корневую папку
Здравствуйте. Не давно нужно было перенести сайт в другой корневой каталог. Был он к примеру с адресом - http://site.com.ua, а стал с -...

Обработка документов и перенос в другую папку на PHP
Доброго времени суток. Свела судьба с Лотусом ... учусь разбирать почту. В папку spider\atm\upc с помощью правил в Notes переносятся...

Webbrowser перенос кэша в другую папку и загрузка от туда
Нужна помощь помогите, как можно реализовать так, чтобы кэш грузился в &quot;свою&quot; нужную мне директорию и после этого подгружался от...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru