This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Switch branches/tags
Branches Tags
Could not load branches
Nothing to show
Could not load tags
Nothing to show
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Cancel Create
- Local
- Codespaces
HTTPS GitHub CLI
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more about the CLI.
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
ПОИСК ЗАБЫТЫХ КОШЕЛЬКОВ БИТКОИН — ОЧЕРЕДНОЙ СКАМ
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
Latest commit message
Commit time
README.md
Проект Finder
Технологии и инструменты:
Создал программу для поиска файлов.
- Программа должна искать данные в заданном каталоге и подкаталогах.
- Имя файла может задаваться, целиком, по маске, по регулярному выражению (не обещаю) .
- Программа должна собираться в jar
- Программа должна записывать результат в файл.
- В программе должна быть валидация ключей и подсказка.
Проверка вашей установки Java
Для работы с любым программным обеспечением, написанным на JAVA, у вас должен быть установлен Java SE Development Kit (JDK). Я использую jdk-14.0.1. Если у вас все настроено правильно, вы сможете открыть командное окно и выполнить следующие две команды:
Обе команды должны завершиться успешно и сообщить об одной и той же версии Java.
Команда должна завершиться успешно и сообщит версию Maven и другую информацию:
- Apache Maven 3.6.3
- Maven home: C:Toolsapache-maven-3.6.3bin.
- Java version: 14.0.1, vendor: Oracle Corporation.
Компиляция и запуск
Для компиляции проекта, неберите: mvn package
- Программа должна собираться в jar и запускаться с обязательным указанием всех четырёх параметров. Запуск программы без параметров java -jar find.jar выводит в консоль, подсказку с параметрами.
- В результате работы программы, будет сформирован файл результатов, который сохраниться в текстовом формате UTF8 кодировкой. Сохранение файла происходит в папке расположения программы.
- На диске C: будут найдены все файлы с любым именем и только с расширением txt. Результат поиска будет записан в файл log.txt. Файлы с запрещённым доступом, пропускаются, о чём будет сообщено в консоли.
java -jar find.jar -d=c:/ -n=*.txt -t=mask -o=log.txt
43 Рекурсивный обход файлов Python
- На диске C: будут найдены все файлы с именем file и с расширением txt. Результат поиска будет записан в файл log.txt
java -jar find.jar -d=c:/ -n=file.txt -t=name -o=log.txt
- На диске C: будут найдены все файлы, внутри которых найдено слово Integral. Поиск case sensitive. Результат поиска будет записан в файл log.txt
java -jar find.jar -d=c:projectsjob4j_finder, -n=Integral, -t=content, -o=log.log
- На диске C: будут найдены все файлы с именем в котором обязателно присутствуют от трёх и более цыфр и с любым расширением. Результат поиска будет записан в файл log.txt.
java -jar find.jar -d=c:/ -n=d.* -t=regex -o=log.txt
-d — директория, в которой начинать поиск.
-n — имя файла, маска, либо регулярное выражение.
-t — тип поиска: mask искать по маске, name по полному совпадение имени, regex по регулярному выражению, content по подстроке в файле.
-o — результат записать в файл.
Ключи, регистронезависимые: -T=content = -t=content .
Источник: github.com
Как написать программу для поиска файлов
: 95
Популярность: 6380
Сказал(а) спасибо: 631
Поблагодарили 460 раз(а) в 379 сообщениях
Пишем программу для поиска файлов.
Ну что же, давайте попробуем написать программу, которая бы выдавала список всех программ с расширением *.exe в указанной директории, а затем при нажатии на кнопку включалась бы выбранная программа.
Кидаем на форму «TListBox» — в него мы будем выводить список найденных файлов. Обработчик событий для нашей первой кнопки изменим на такой:
procedure TForm1.Button1Click(Sender: TObject); var sr:TSearchRec; Result:word; begin ChDir(‘C:windows’);//меняем папку на C:Windows Result := FindFirst (‘*.exe’,faAnyFile,sr); ListBox1.Clear; While result=0 do Begin Result:=FindNext (sr); ListBox1.Items.add(sr.name); End; end;
Как вы можете наблюдать, мы не сделали ничего сложного, просто организовали цикличный проход по директории C:Windows, который прекращается, как только функции возвращает не ноль. Функция ChDir в нашем случае используется для смены папки с текущей на папку C:windows
Этот способ лишь находит файлы в том каталоге, который задан переменной Path:String. Поэтому я думаю, что стоит написать алгоритм поиска файлов в каждой найденной директории.
У меня расширенная процедура поиска выглядит вот так:
procedure ffind(cat:string); //каталог, откуда начать поиск var sea:TSearchRec; res:integer; //результат поиска (0 или нет) begin res:=FindFirst(cat+’*.*’,faAnyFile,sea); //ищем первый файл res:=findNext(sea);//ищем следующий файл While res=0 do begin if (Sea.Attr=faDirectory) and ((Sea.Name=’.’)or(Sea.Name=’..’)) then//чтобы не было файлов . и.. begin Res:=FindNext(sea); Continue;//продолжаем цикл end;
if (Sea.Attr=faDirectory) then//если нашли директорию, то ищем файлы в ней begin Ffind(cat+Sea.Name+»);//рекурсивно вызываем нашу процедуру Res:=FindNext(Sea);//ищем след. файл Continue;//продолжаем цикл end; form1.ListBox1.Items.Add(Sea.Name);//добавляем в Listbox:Tlistbox имя файла Res:=FindNext(Sea);//ищем след. файл end; FindClose(Sea);//освобождаем пересенную поиска end;
Здесь мы с вами использовали процедуру FindClose(var sea: TsearchRec) — она необходима для освобождения поисковой переменной. Для того, чтобы наша с вами программа не выглядела подвисшей, можно добавить Application.ProcessMessages в начало нашей процедуры.
Кидаем на форму еще одну кнопку для того, чтобы по ее нажатии запускать выбранную в ListBox’e программу. Обработчик события Onclick для нашей второй кнопки у меня получился таким:
procedure TForm1.Button2Click(Sender: TObject); begin WinExec(pchar(listbox1.Items[listbox1.itemindex]),sw_show); end;
Т.к. файлы находятся в директории Windows, то при вызове метода WinExec путь к файлам можно не указывать, а если вы используете какую-либо другую директорию, то вызов метода WinExec должен быть таким:
WinExec(pchar(‘C:Путь к вашей папке’+listbox1.Items[listbox1.itemindex]),sw_show);
А если вы просто хотите искать файлы в указанном пользователем каталоге можно использовать компонент DirectoryListBox, который дает доступ к каталогам на вашем компьютере и позволяет менять текущий каталог двойным нажатием мыши. Узнаем выбранный каталог так:
DirectoryListBox1.Directory
Именно поэтому в обработчике первой кнопки, убираем вызов функции ChDir. А в обработчике второй кнопки вставить приведенную выше конструкцию.
Таким образом у нас с вами получается вот такой код:
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FileCtrl; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; ListBox1: TListBox; Button2: TButton; DirectoryListBox1: TDirectoryListBox; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private < Private declarations >public < Public declarations >end; var Form1: TForm1; implementation procedure TForm1.Button1Click(Sender: TObject); var sr:TSearchRec; Result:word; begin Result := FindFirst (‘*.exe’,faAnyFile,sr); ListBox1.Clear; While result=0 do Begin Result:=FindNext (sr); ListBox1.Items.add(sr.name); End; end; procedure TForm1.Button2Click(Sender: TObject); begin WinExec(pchar(DirectoryListBox1.Directory+»+listbox1.Items[listbox1.itemindex]),sw_show); end; end.
Источник: zhyk.org
Записки программиста
Продолжаем дружно вспоминать WinAPI. В отличие от всех предыдущих заметок сегодня мы напишем первую программу, которая делает что-то действительно полезное. А именно, позволяет найти файл на жестком диске по части его имени.
В этом нам помогут следующие процедуры и структуры данных.
GetLogicalDrives ( ) ;
Процедура GetLogicalDrives возвращает битовую маску, по которой можно судить, какие диски есть в системе. Например, если 0-ой бит установлен в единицу, значит диск «A:» есть, иначе его нет. Аналогично, 1-ый бит соответствует диску «B:», 2-ой — диску «C:», и так далее до 25-го бита.
FindFirstFile ( szPath ,
В качестве аргументов принимает строку типа «C:windows*.exe» и указатель на структуру WIN32_FIND_DATA. В случае успеха процедура возвращает хэндл, соответствующий поиску, а в fdFindData записывается информация о первом найденном файле — его имя, размер, атрибуты, время создания и так далее. В случае ошибки возвращается INVALID_HANDLE_VALUE.
FindNextFile ( hFind ,
Когда поиск завершен, FindClose закрывает хэндл, полученный от FindFirstFile.
Теперь с помощью перечисленных процедур, а также процедур, с которыми мы с вами познакомились в заметке Пишем простое консольное приложение на чистом WinAPI, не представляет труда написать программу, которая рекурсивно ищет файлы на всех дисках в системе, выводя те имена файлов, в которых содержится заданная в качестве аргумента подстрока:
#include
#include
#define STRLEN(x) (sizeof(x)/sizeof(x[0]) — 1)
VOID ProcessFoundFile ( HANDLE CONST hStdOut , LPWSTR CONST szPath ,
WIN32_FIND_DATA CONST * CONST fdFindData ,
LPWSTR CONST lpSearch ) {
TCHAR szEnd [ ] = L » r n » ;
DWORD dwTemp ;
if ( NULL != StrStrI ( fdFindData -> cFileName , lpSearch ) ) {
WriteConsole ( hStdOut , szPath , lstrlen ( szPath ) ,
WriteConsole ( hStdOut , szEnd , STRLEN ( szEnd ) ,
}
}
VOID FindFirstFileFailed ( HANDLE CONST hStdOut , LPWSTR CONST szPath ) {
TCHAR CONST szMsgTmpl [ ] = L «FindFirstFile() failed, »
L «GetLastError() = %d, szPath = %s r n » ;
TCHAR szMsg [ MAX_PATH * 2 ] ;
DWORD dwTemp ;
wsprintf ( szMsg , szMsgTmpl , GetLastError ( ) , szPath ) ;
WriteConsole ( hStdOut , szMsg , lstrlen ( szMsg ) ,
}
VOID RecursiveSearch ( HANDLE CONST hStdOut , LPWSTR szPath ,
LPWSTR CONST lpSearch ) {
WIN32_FIND_DATA fdFindData ;
HANDLE hFind ;
TCHAR * CONST lpLastChar = szPath + lstrlen ( szPath ) ;
lstrcat ( szPath , L «*» ) ;
hFind = FindFirstFile ( szPath ,
* lpLastChar = ‘ ‘ ;
if ( INVALID_HANDLE_VALUE == hFind ) {
FindFirstFileFailed ( hStdOut , szPath ) ;
return ;
}
do
if ( ( 0 == lstrcmp ( fdFindData. cFileName , L «.» ) )
lstrcat ( szPath , fdFindData. cFileName ) ;
if ( fdFindData. dwFileAttributes \ » ) ;
RecursiveSearch ( hStdOut , szPath , lpSearch ) ;
} else {
ProcessFoundFile ( hStdOut , szPath ,
}
* lpLastChar = ‘ ‘ ;
} while ( FindNextFile ( hFind ,
VOID SearchOnAllDrives ( HANDLE CONST hStdOut , LPWSTR CONST lpSearch ) {
TCHAR szCurrDrive [ ] = L «A: \ » ;
TCHAR szPath [ MAX_PATH + 1 ] ;
DWORD i , dwDisksMask = GetLogicalDrives ( ) ;
for ( i = 0 ; i < 26 ; i ++ ) {
if ( dwDisksMask
RecursiveSearch ( hStdOut , szPath , lpSearch ) ;
}
dwDisksMask >>= 1 ;
szCurrDrive [ 0 ] ++;
}
}
INT main ( ) {
DWORD dwTemp ;
INT nArgs = 0 ;
LPWSTR CONST lpCmd = GetCommandLine ( ) ;
LPWSTR CONST * CONST lpArgs = CommandLineToArgvW ( lpCmd ,
HANDLE CONST hStdOut = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
CONST TCHAR szUsage [ ] = L «Usage: find.exe r n » ;
if ( nArgs < 2 ) {
WriteConsole ( hStdOut , szUsage , STRLEN ( szUsage ) ,
} else {
SearchOnAllDrives ( hStdOut , lpArgs [ 1 ] ) ;
}
LocalFree ( ( PVOID ) lpArgs ) ;
ExitProcess ( 0 ) ;
}
Чтобы эта программа успешно заработала, нужно кое-что поменять в свойствах нашего шаблонного проекта. Во-первых, тип приложения нужно изменить с GUI на CLI. Во-вторых, в свойствах проекта нужно найти Linker → Input → Additional Dependencies, и прописать там «shlwapi.lib» без кавычек. Зачем это нужно, будет рассказано чуть ниже.
Также в свойствах проекта нужно указать аргументы, передаваемые программе при ее запуске из IDE. Для этого идем в Debugging → Command Arguments и пишем там, например, «.txt».
Если теперь скомпилировать и запустить программу, вы увидите примерно следующее:
В приведенном выше коде есть несколько тонких моментов. Во-первых, как вы могли заметить, в нем активно используется макрос CONST. Он определен в файле windef.h как:
#define CONST const
Как большие специалисты по Си (вы же прочитали Кернигана и Ритчи, как я совевтовал?), вы, конечно же, прекрасно знаете, для чего нужно ключевое слово const. Но чисто на всякий случай освежим эти знания. Ключевое слово const говорит о том, что переменная является неизменяемой. Например, если написать:
HANDLE CONST hStdOut = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
… а затем попытаться присвоить переменной hStdOut новое значение, компилятор откажется компилировать программу. Когда в дело вступают указатели, все становится чуточку интереснее. Проще всего показать это на примерах:
// неизменяемый указатель на массив неизменяемых LPWSTR
LPWSTR CONST * CONST lpArgs = CommandLineToArgvW ( lpCmd ,
// неизменяемый указатель на массив изменяемых TCHAR’ов
TCHAR * CONST lpLastChar = szPath + lstrlen ( szPath ) ;
// изменяемый указатель на массив неизменяемых TCHAR’ов
// TCHAR CONST * lpLastChar = .
Вместо «HANDLE CONST» также можно писать «CONST HANDLE». Учитывая, что в Си, как известно, можно с легкостью прострелить себе ногу, по возможности следует использовать const как можно чаще. Даже несмотря на то, что из-за него становится несколько сложнее читать код.
Во-вторых, вы могли обратить внимание на использование процедуры StrStrI. Как нетрудно догадаться, она предназначена для сравнения строк без учета регистра. Данная процедура экспортируется динамической библиотекой shlwapi.dll, поэтому нам пришлось написать в коде #include и в свойствах проекта указать, чтобы линковщик использовал библиотеку shlwapi.lib.
Наконец, в-третьих, наверняка вам не дает покоя следующая проверка:
if ( ( 0 == lstrcmp ( fdFindData. cFileName , L «.» ) ) ||
( 0 == lstrcmp ( fdFindData. cFileName , L «..» ) ) ) {
continue ;
}
Так сделано, потому что наряду с обычными файлами и каталогами, FindFirstFile и FindNextFile возвращают информацию о специальных каталогах «.» и «..», которые являются ссылками на текущий и родительский каталоги соответственно. Такая проверка гарантирует, что наш рекурсивный алгоритм не скушает весь стек, обращаясь к каталогам типа «C:..…и так много раз…». Следует обратить внимание, что в Windows имена файлов могут начинаться с точки (cmd.exe → echo 123 > .test ), поэтому имя нужно проверять целиком, а не только его первый символ.
Велика вероятность, что во всем остальном вы сможете разобраться своими силами. В качестве домашнего задания можете попробовать добавить в программу поддержку аргументов, указывающих, на каких именно дисках нужно искать файлы, или с какого каталога следует начать. Также можете попробовать добавить аргумент, задающий строку, которая должна содержаться внутри файла. Тут вам пригодятся процедуры, с которыми мы познакомились в заметке Учимся работать с файлами через Windows API.
Как всегда, приведенный код может быть скомпилирован MinGW и запущен под Wine. Если после прочтения заметки у вас остались вопросы, я буду рад на них ответить.
Дополнение: Как выяснилось, у приведенного кода есть ряд недостатков. Во-первых, при запуске под Wine длина имени файла может превосходить MAX_PATH. Во-вторых, код не учитывает существование симлинков и junction points. В продакшн коде все это должно учитываться.
Вы можете прислать свой комментарий мне на почту, или воспользоваться комментариями в Telegram-группе.
Источник: eax.me