#java #file
#java #файл
Вопрос:
Как я могу проверить, существует ли файл на основе частичного имени файла в Java?
В моем случае файл должен создаваться один раз в день с именем формы DATE_TIMESTAMP.xml
и с этого момента должен добавляться к.
Например: 2011-14-11_1734289.xml
Итак, если файл, имя которого начинается с 2011-14-11
(и сегодня это 2011-14-11), существует, этот файл должен быть добавлен, в противном случае следует создать новый.
Можно File.exist()
передать регулярное выражение? Предоставляют ли какие-либо библиотеки эту функциональность?
Ответ №1:
Сначала убедитесь, что у вас есть File
объект, указывающий на каталог, в котором может потребоваться создать этот файл. После этого вы можете вызвать для него listFiles(FilenameFilter filter). Если он возвращает массив, длина которого не равна 0, это означает, что существует по крайней мере один файл с частичным совпадением имени. Вы могли бы дополнительно использовать это для обнаружения некорректных ситуаций (например, массив длиной больше 1 означает, что слишком много файлов с этой частью имени).
Чтобы использовать это, вам пришлось бы создать реализацию FilenameFilter. Убедитесь, что у него есть конструктор, в который вы передаете частичное имя или шаблон, для которого вам нужно проверить. Регулярные выражения могут и не понадобиться, достаточно простой проверки, чтобы увидеть, содержится ли текущая дата в желаемом формате в имени файла.
В качестве альтернативы вы могли бы использовать listFiles(FileFilter filter)
с реализацией FileFilter вместо FilenameFilter
, если в их названиях могут быть каталоги с датами. Получение единственного File
экземпляра для проверки вместо File
для каталога плюс имя файла может упростить это, используя метод isDirectory()
of File
.
Комментарии:
1. G_H, никогда не использовал listFiles (фильтр FilenameFilter). Это выглядит как интересный момент. Я дам вам отзыв, как только проверю решение.
Ответ №2:
Если вы откроете имя файла, которое хотите записать, Java создаст его, если оно не существует, и добавит, если оно существует (если вы специально не установите флажок перезаписывать, в этом случае оно перезапишется).
Итак, открытие простого FileWriter или FileOutputStream сделало бы свое дело.
Комментарии:
1. NimrodArgov, я отредактировал сообщение. Файл создан один раз и добавлен несколько раз, поэтому мне нужно проверять, существует ли он каждый раз.
2. Если вы основываете имя файла на дате (или на чем угодно, если уж на то пошло), файл все равно будет создан при первой попытке записи в него, а затем будет добавлен в последующие разы. Вопрос в том, как вы выбираете имя файла.
Ответ №3:
Использование filereader или bufferedreader сделает свое дело. В обоих из них есть проверенные исключения, поэтому вам придется поместить их в блок try catch. В блоке catch вы можете создать файл, если будет обнаружено исключение FileNotFoundException или IOException, соответственно.
Комментарии:
1. Зачем мне нужно использовать
FileReader
для простой проверки существования файла? Кроме того, вы не обращаетесь к корню вопроса — сказать «использоватьFileReader
» не более полезно (и менее корректно), чем сказать «ИспользоватьFile.exists()
«.
Ответ №4:
Вы можете использовать File
класс и его методы:
В нем также есть другие методы, которые могут быть полезны.
Обновить:
Возможно, вы захотите использовать listFiles()
метод.
ВОЗВРАТ: Массив абстрактных путей, обозначающих файлы и каталоги в каталоге, обозначенном этим абстрактным путем. Массив будет пустым, если каталог пуст.
Комментарии:
1. Я знаю). Проблема в другом. Когда я записываю в файл не в первый раз, он создает новый по метке времени, и мне нужно записать в один файл в объеме одного дня
Ответ №5:
Есть несколько жизнеспособных способов решить то, что вы хотите сделать, в зависимости от ваших конкретных требований.
-
Используйте
Files.newDirectoryStream(Path, String)
nio
Утилиты Java 7 включают в себя метод, который позволяет выполнять фильтрацию по глобусу, что позволит вам сопоставлять имена файлов с частями точно так, как вы запрашиваете. КлассыFiles
иPath
немного концептуально отличаются от устаревшегоFile
класса, но они гораздо более надежные и мощные. Если вы используете Java 7 , я бы рекомендовал использоватьPath
s в новом коде. Проверка существования будет выглядеть примерно так:try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, "2011-14-11*")) { Iterator<Path> streamIter = stream.iterator(); if(streamIter.hasNext()) { System.out.println("File exists: " streamIter.next()); if(streamIter.hasNext()) { throw new IllegalStateException("Multiple filenames matched the glob!"); } } else { System.out.println("File does not exist"); } }
Приведенный выше шаблон все еще несколько подвержен ошибкам, что нам действительно следует сделать, так это определить метод, который возвращает
Path
объект и скрывает поведение при поиске файла. Рассмотрим:public Path getDatedFile(String date) { try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, date "*")) { Iterator<Path> streamIter = stream.iterator(); if(streamIter.hasNext()) { Path file = streamIter.next(); if(streamIter.hasNext()) { throw new IllegalStateException("Multiple filenames matched the glob!"); } return file; } else { Path file = dir.resolve(date "_" getTimestamp() ".xml"); Files.createFile(file); // or write some sort of header here return file; } } }
Использование этого метода означает, что весь ваш код может просто вызывать этот метод, и все вызывающие пользователи могут быть уверены, что файл существует. Обратите внимание, что вы могли бы реализовать эквивалентный метод с помощью
File
, если вы не используете Java 7. -
Избегайте этой схемы именования
На самом деле, у вас возникают проблемы, потому что вы не знаете фактического имени, с которым был создан файл (если он уже существует). Зачем вам нужно использовать схему именования, которую вы не можете предсказать? Поскольку вам нужен ровно один файл в день, что в этом плохого
DATE.xml
? Использование этой более сложной схемы именования приводит к всевозможным ошибкам и дополнительным сложностям, поскольку теперь каждый фрагмент кода, работающий с файлом, должен вручную проверять наличие похожих имен файлов, а не просто существование файла с известным именем. На первый взгляд кажется, чтоTIMESTAMP
нужно просто записать, когда файл был создан — почему бы не поместить эти данные в сам файл? Например.:2011-14-11.xml: <root created="1734289"> ...