2013-08-28 2 views
6

Мне нужно прочитать файл, содержащий список строк. Я пытаюсь следовать совету в this post. Оба решения требуют использования FileUtils.readLines, но в качестве параметра используйте String, а не File.Как получить ресурс Java в качестве файла?

Set<String> lines = new HashSet<String>(FileUtils.readLines("foo.txt")); 

Мне нужен File.

This postбудет быть моим вопросом, за исключением того, что OP был отговорен от использования файлов полностью. Мне нужен файл, если я хочу использовать метод Apache, который является моим предпочтительным решением для моей первоначальной проблемы.

Мой файл небольшой (сотни строк или около того) и одноэкранный экземпляр программы, поэтому мне не нужно беспокоиться о наличии другой копии файла в памяти. Поэтому я мог бы использовать более простые методы для чтения файла, но до сих пор это выглядит так: FileUtils.readLines может быть намного чище. Как перейти от ресурса к файлу.

+0

Если это является ресурсом пути к классам, вы не должны использовать тип «Файл». Подумайте об использовании метода Google [Guava library] (https://code.google.com/p/guava-libraries/) 'Resources.readLines'. – McDowell

ответ

9

Apache Commons-IO имеет IOUtils class, а также FileUtils, который включает readLines method, аналогичный файлу FileUtils.

Таким образом, вы можете использовать getResourceAsStream или getSystemResourceAsStream и передать результат, что IOUtils.readLines получить List<String> содержимого файла:

List<String> myLines = IOUtils.readLines(ClassLoader.getSystemResourceAsStream("my_data_file.txt")); 
+0

lol, так что еще один вопрос, принимающий ответ, который обходит проблему получения файла. Java действительно не похож на файл. – djechlin

+0

Не имеет к этому никакого отношения. Файл не является системным агностиком, Stream. – JoshDM

+0

@djechlin «Файл» - это фактический файл в файловой системе, у которого есть путь. Ресурсы могут быть частью файла jar, и вы не можете ссылаться только на часть jar (или zip) по пути. Что вы можете сделать, так это получить поток в реальном файле или потоке в сжатый файл в архиве, который также распаковывается «на лету». – zapl

2

Я предполагаю, что файл, который вы хотите прочитать, является истинным ресурсом в вашем пути к классам, а не просто каким-либо произвольным файлом, к которому вы можете просто получить доступ через new File("path_to_file");.

Попробуйте использовать ClassLoader, где resource представляет собой представление пути к вашему файлу ресурсов в вашем пути к классу.

Допустимые String значения для resource могут включать в себя:

  • "foo.txt"
  • "com/company/bar.txt"
  • "com\\company\\bar.txt"
  • "\\com\\company\\bar.txt"

и путь не ограничивается com.company

Соответствующий код, чтобы получить File не в баночке:

File file = null; 

try { 

    URL url = null; 
    ClassLoader classLoader = {YourClass}.class.getClassLoader(); 

    if (classLoader != null) { 

     url = classLoader.getResource(resource); 
    } 

    if (url == null) { 

     url = ClassLoader.getSystemResource(resource); 
    } 

    if (url != null) { 

     try { 

      file = new File(url.toURI()); 

     } catch (URISyntaxException e) { 

      file = new File(url.getPath()); 
     } 
    } 

} catch (Exception ex) { /* handle it */ } 

// file may be null 

С другой стороны, если ваш ресурс находится в баночке, вы должны будете использовать Class.getResourceAsStream(resource); и цикл через файл, используя BufferedReader для имитации вызова до readLines().

+0

Должен ли ресурс быть строкой, например. "' /com/mysite/app/file.txt"'? – djechlin

+0

Нет, не с предыдущим '/'. Я тестировал его на Windows 7 и обновлял свои успешные тестовые примеры. Не работает с '.' Как разделитель путей. – JoshDM

+0

После рассмотрения http://stackoverflow.com/questions/676097/java-resource-as-file один из альтернативных ответов в моем ответе похож, но не настолько широкий по объему. – JoshDM

0

, используя ресурс для чтения файла в строку:

String contents = 
FileUtils.readFileToString(
    new File(this.getClass().getResource("/myfile.log").toURI())); 

с помощью InputStream:

List<String> listContents = 
IOUtils.readLines(
    this.getClass().getResourceAsStream("/myfile.log")); 
Смежные вопросы