Найти все файлы с расширением java
Я хочу создать приложение Java для выявления дубликатов. Пока я могу найти дубликаты только по имени, но мне также нужны размер, тип файла и, возможно, содержимое. Это мой код, использующий HashMap :
Recursive Pattern Matching
Searching for files that match a particular pattern goes hand-in-hand with walking a file tree. How many times do you know a file is somewhere on the file system, but where? Or perhaps you need to find all files in a file tree that have a particular file extension.
The Find example does precisely that. Find is similar to the UNIX find utility, but has pared down functionally. You can extend this example to include other functionality. For example, the find utility supports the -prune flag to exclude an entire subtree from the search. You could implement that functionality by returning SKIP_SUBTREE in the preVisitDirectory method. To implement the -L option, which follows symbolic links, you could use the four-argument walkFileTree method and pass in the FOLLOW_LINKS enum (but make sure that you test for circular links in the visitFile method).
To run the Find application, use the following format:
The pattern is placed inside quotation marks so any wildcards are not interpreted by the shell. For example:
Это должно быть просто, но я не могу его получить - "напишите программу, которая ищет конкретное имя файла в данном каталоге."Я нашел несколько примеров жестко закодированного имени файла и каталога, но мне нужно, чтобы и dir, и имя файла были введены пользователем.
вы можете попробовать что-то вроде этого:
Это похоже на вопрос домашней работы, поэтому я просто дам вам несколько советов:
попробуйте дать хорошие отличительные имена переменных. Здесь вы использовали "fileName" сначала для каталога, а затем для файла. Это сбивает с толку и не поможет вам решить проблему. Используйте разные названия для разных вещей.
вы не используете сканер ни для чего, и это не нужно здесь, избавиться от него.
кроме того, метод accept должен возвращать логическое значение. Прямо сейчас вы пытаетесь вернуть строку. Boolean означает, что он должен возвращать true или false. Например return a > 0; может возвращать true или false, в зависимости от значения a. Но!--1--> просто вернет значение fileName, которое является строкой.
Если вы хотите использовать динамический фильтр имени файла, вы можете реализовать FilenameFilter и передать в конструкторе динамическое имя.
конечно, это означает, что вы должны создавать экземпляр каждый раз, когда класс (накладные расходы), но он работает
затем вы используете, где вам нужно:
С * * Java 8 * есть альтернатива, которая использует потоки и лямбды:
Так это будет печатать все файлы рекурсивно:
и это будет искать файл:
я использовал другой подход для поиска файла с помощью стека.. имея в виду, что внутри папки могут быть папки. Хотя это не быстрее, чем поиск windows (и я не ожидал этого, хотя), но это определенно дает правильный результат. Пожалуйста, измените код, как вы хотите. Этот код был первоначально сделан для извлечения пути к файлу определенного расширения файла:). Не стесняйтесь оптимизировать.
следующий код помогает найти файл в каталоге и открыть его местоположение
пример использования try-with-resources шаблон рекомендуется в руководстве API. Это гарантирует, что независимо от обстоятельств поток будет закрыт.
в Java 8, вы можете сделать это
который будет печатать все файлы в папке, исключая все каталоги. Если вам нужен список, выполните следующие действия:
если вы хотите вернуть List вместо List просто карта это:
вы также должны убедиться, чтобы закрыть поток! В противном случае вы можете столкнуться с исключением, сообщающим вам, что слишком много файлов открыты. Читать здесь для получения дополнительной информации.
все ответы на этот вопрос, которые используют новые функции Java 8, пренебрегают закрытием потока. Примером в принятом ответе должно быть:
из javadoc Files.walk способ:
возвращаемый поток инкапсулирует один или несколько DirectoryStreams. Если своевременное избавление ресурсов файловой системы необходимо, конструкция try-with-resources должна использоваться для обеспечения метод close stream вызывается после потоковые операции завершены.
просто пройдите через все файлы, используя Files.walkFileTree (Java 7)
вы также можете создать фильтр, который затем может быть передан в newDirectoryStream способ выше
Если вы хотите больше опций, вы можете использовать эту функцию, которая направлена на заполнение arraylist файлов, присутствующих в папке. Варианты : recursivility и шаблон, чтобы соответствовать.
Я думаю, что это хороший способ прочитать все файлы в папке и подпапке
простой пример, который работает с Java 1.7 рекурсивно список файлов в каталогах, указанных в командной строке:
хотя я согласен с Ричем, Орианом и остальными для использования:
почему-то все примеры здесь используется абсолютное путь (т. е. полностью от корня или, скажем, буквы диска (C:\) для windows..)
Я хотел бы добавить, что можно использовать относительные путь-хорошо. Итак, если вы pwd (текущий каталог / папка) является folder1, и вы хотите разобрать folder1 / subfolder, вы просто пишете (в коде выше вместо ):
вот безопасное решение, хотя и не такое элегантное, как Java 8 Files.walk(..) :
список файлов из тестовой папки в пути к классу
вы можете фильтровать любые текстовые файлы или любое другое расширение ..просто замените его .MP3
чтобы расширить принятый ответ, я сохраняю имена файлов в ArrayList (вместо того, чтобы просто сбрасывать их в систему.из.println) я создал вспомогательный класс "MyFileUtils", чтобы он мог быть импортирован другими проектами:
я добавил полный путь к имени файла. Вы бы использовали его так:
ArrayList передается "value", но значение используется для указания на тот же объект ArrayList, живущий в куче JVM. Таким образом, каждый вызов рекурсии добавляет имена файлов в тот же ArrayList (мы не создаем новый ArrayList при каждом рекурсивном вызове).
Теперь, чтобы получить файлы из определенной папки, предположим, у вас есть папка с именем "res" в папке ресурсов, просто замените:
Если вы хотите иметь доступ в ваш com.пакет "название" тут:
Это будет читать указанные файлы расширения файла в заданном пути (также выглядит вложенные папки)
Файл.список()
Самым простым методом для перечисления имен файлов и папок в заданном каталоге без обхода подкаталогов является вспомогательный метод .list () , который возвращает массив String s.
Мы делаем это с помощью метода .list() в экземпляре Файла :
Используя простой цикл для каждого , мы перебираем массив и выводим Строку s.
При использовании этого подхода все элементы в каталоге Кодирование музыки не отображаются, и недостатком этого подхода является то, что мы действительно ничего не можем сделать с самими файлами. Мы только узнаем их имена. Это полезно, когда мы просто хотим взглянуть на файлы по номиналу.
Фильтр имен файлов
Еще одна вещь, которую мы можем сделать с помощью метода .list () , – это создать Фильтр имен файлов для возврата только тех файлов, которые мы хотим:
Запуск этого фрагмента кода приведет к:
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Здесь мы заполнили Поток , используя метод .walk () , передав аргумент Пути|/. Класс Пути состоит из статических методов , которые возвращают Путь на основе строкового URI - и, используя Путь , мы можем легко найти файл.
Путь , Пути , Файлы и многие другие классы принадлежат пакету java.nio , который был представлен в Java 7 как более современный способ представления файлов неблокирующим способом.
Затем с помощью Collections Framework создается список.
Запуск этого фрагмента кода приведет к:
Файл.listFiles()
Подобно предыдущему методу, этот метод можно использовать для возврата имен файлов и каталогов, но на этот раз мы получаем их в виде массива объектов File , что дает нам возможность напрямую манипулировать ими:
Теперь давайте углубимся в файловую систему, используя рекурсию и еще несколько методов для использования с Файлом объектом:
Вывод
Обработка файлов каким-либо образом является основной задачей для большинства языков программирования, и это включает в себя возможность перечислять и находить файлы в файловой системе. Чтобы манипулировать файлами, нам нужно знать, где они находятся. Наличие обзора файлов в каталоге имеет первостепенное значение, если мы хотим этого добиться, особенно если мы можем выполнять операции с ними с помощью итерации.
В этой статье мы показали несколько различных способов в Java перечисления файлов в файловой системе, используя как линейный, так и рекурсивный подходы.
If you have ever used a shell script, you have most likely used pattern matching to locate files. In fact, you have probably used it extensively. If you haven't used it, pattern matching uses special characters to create a pattern and then file names can be compared against that pattern. For example, in most shell scripts, the asterisk, * , matches any number of characters. For example, the following command lists all the files in the current directory that end in .html :
The java.nio.file package provides programmatic support for this useful feature. Each file system implementation provides a PathMatcher . You can retrieve a file system's PathMatcher by using the getPathMatcher(String) method in the FileSystem class. The following code snippet fetches the path matcher for the default file system:
The string argument passed to getPathMatcher specifies the syntax flavor and the pattern to be matched. This example specifies glob syntax. If you are unfamiliar with glob syntax, see What is a Glob.
Glob syntax is easy to use and flexible but, if you prefer, you can also use regular expressions, or regex, syntax. For further information about regex, see the Regular Expressions lesson. Some file system implementations might support other syntaxes.
If you want to use some other form of string-based pattern matching, you can create your own PathMatcher class. The examples in this page use glob syntax.
Once you have created your PathMatcher instance, you are ready to match files against it. The PathMatcher interface has a single method, matches , that takes a Path argument and returns a boolean: It either matches the pattern, or it does not. The following code snippet looks for files that end in .java or .class and prints those files to standard output:
4 ответа
Я использовал MessageDigest и проверил некоторые файлы и нашел дубликаты в соответствии со всеми критериями, которые я перечислил в заголовке и описании. Спасибо вам всем.
И это результат после внедрения в код поиска для дубликатов
Я сделал это приложение давно, я нашел для вас часть его исходного кода, если вы хотите изучить.
Этот метод работает путем сравнения обоих файлов байтов.
Объедините этот метод с проверкой имени и расширения, и вы готовы к работе.
Копировать - вставить - пример
создать класс, который расширяет File
читать базовый каталог
Считая, что 2 файла равны, если они имеют одинаковое расширение и одинаковый размер файла, это просто вопрос создания объекта, который представляет это «равенство». Итак, вы бы сделали что-то вроде:
(и заполните все недостающие шаблоны: конструктор, toString, equals, hashCode и getters. См. Project Lombok's @Value чтобы сделать это легко, если хотите). Вы можете получить расширение файла по имени файла, используя fileName.lastIndexOf('.') и fileName.substring(lastIndex) . С lombok все, что вам нужно написать:
Затем используйте FileEquality объекты в качестве ключей в вашей хэш-карте вместо строк. Однако то, что у вас есть, скажем, «foo.txt» и «bar.txt», размер которых составляет 500 байт, не означает, что эти 2 файла являются дубликатами. Итак, вы тоже хотите, чтобы контент включался, но если вы расширите свой класс FileEquality , включив в него содержимое файла, то появятся 2 вещи:
Если вы все равно проверяете содержимое, какое значение имеет размер и расширение файла? Если содержимое foo.txt и bar.jpg точно одинаковое, они дубликаты, нет? Зачем беспокоиться. Вы можете передать содержимое как byte[] , но учтите, что написание правильной реализации hashCode() и equals() (которые необходимы, если вы хотите использовать этот объект в качестве ключа для хэш-карт), становится немного сложнее К счастью, @Value Ломбока все сделает правильно, поэтому я предлагаю вам это использовать.
Это подразумевает, что полнота содержимого файла находится в памяти процесса вашей JVM. Если вы не проверяете очень маленькие файлы, вам просто не хватит памяти. Вы можете несколько абстрагироваться от этого, не сохраняя весь контент файла, а сохраняя хэш контента. Google вокруг, как вычислить sha-256 хэш файла в Java. Поместите это значение в ваш FileEquality , и теперь вы избежите проблемы с памятью. Теоретически возможно иметь 2 файла с разным содержимым, которые, тем не менее, хэшируют с одинаковым значением sha-256, но вероятность этого астрономическая, и, более того, sha-256 разработан таким образом, что его невозможно математически преднамеренно сделайте 2 таких файла, чтобы связываться с вашим приложением. Поэтому предлагаю вам просто доверять хешу :)
Обратите внимание, конечно, что хеширование всего файла требует чтения всего файла, поэтому, если вы запустите свой поиск дубликатов в каталоге, содержащем, скажем, файлы объемом 500 ГБ, тогда вашему приложению потребуется минимальное чтение 500 ГБ, что будет занять некоторое время
Многие приложения каким-то образом обрабатывают файлы, и манипулирование файлами является одним из основных знаний на любом языке программирования.
Чтобы манипулировать файлами, нам нужно знать, где они находятся. Наличие обзора файлов в каталоге имеет первостепенное значение, если мы хотим этого добиться, особенно если мы можем выполнять операции с ними с помощью итерации. В Java есть несколько способов сделать это, которые мы покажем в этой статье.
Для простоты все примеры будут написаны для следующего дерева файлов:
Файлы.прогулка()
В Java 8 и более поздних версиях мы можем использовать файл java.nio.Файлы класс для заполнения потока и использования его для просмотра файлов и каталогов и в то же время рекурсивного обхода всех подкаталогов.
Обратите внимание, что в этом примере мы будем использовать лямбда-выражения:
Читайте также: