2013-04-01 4 views
126

Мой проект имеет следующую структуру:Как загрузить файл из папки ресурсов?

/src/main/java/ 
/src/main/resources/ 
/src/test/java/ 
/src/test/resources/ 

У меня есть файл в /src/test/resources/test.csv и я хочу, чтобы загрузить файл из модульного тестирования в /src/test/java/MyTest.java

У меня есть этот код, который не работал. Он жалуется «Нет такого файла или каталога».

BufferedReader br = new BufferedReader (new FileReader(test.csv)) 

Я также попытался это

InputStream is = (InputStream) MyTest.class.getResourcesAsStream(test.csv)) 

Это также не работает. Он возвращает null. Я использую Maven для создания моего проекта.

+0

Не работает как?Какая у вас ошибка? –

+0

он возвращает null – codereviewanskquestions

+6

попробуйте этот 'this.getClass(). GetResource ("/test.csv ")' – SRy

ответ

123

Попробуйте следующее:

ClassLoader classloader = Thread.currentThread().getContextClassLoader(); 
InputStream is = classloader.getResourceAsStream("test.csv"); 

Если выше не работает, различные проекты, которые были добавлены в следующий класс: ClassLoaderUtil (код here).

Вот некоторые примеры того, как используется этот класс:

src\main\java\com\company\test\YourCallingClass.java 
src\main\java\com\opensymphony\xwork2\util\ClassLoaderUtil.java 
src\main\resources\test.csv
// java.net.URL 
URL url = ClassLoaderUtil.getResource("test.csv", YourCallingClass.class); 
Path path = Paths.get(url.toURI()); 
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8); 
// java.io.InputStream 
InputStream inputStream = ClassLoaderUtil.getResourceAsStream("test.csv", YourCallingClass.class); 
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); 
BufferedReader reader = new BufferedReader(streamReader); 
for (String line; (line = reader.readLine()) != null;) { 
    // Process line 
} 
+10

thx для ответа, не могли бы вы объяснить, почему мы должны использовать этот очень специфический загрузчик, но не класс? –

+1

отлично, я настолько глуп, что я использовал 'Object.class.getClassLoader();', из статического контекста, который не работал - это предложение делает - ну почти, оно вводит '% 20' для пробелов, которое дает me a FileNotFoundException' – ycomp

+3

@ycomp Поскольку getResource возвращает URL-адрес, а не файл. Метод getFile для java.net.URL ** не конвертирует URL в файл; он просто возвращает путь и часть запроса URL-адреса. Вы даже не должны пытаться преобразовать его в файл; просто вызовите openStream и прочитайте это. – VGR

25

Try:

InputStream is = MyTest.class.getResourceAsStream("/test.csv"); 

IIRC getResourceAsStream() по умолчанию является относительно пакета класса.

0

ли работа коды, когда он не работает на Maven-сборки банки, например, при работе с вашего IDE ? Если да, убедитесь, что файл фактически включен в банку. Папка ресурсов должна быть включена в файл pom, в <build><resources>.

+0

При использовании eclipse и кода запуска из самой IDE. Как мы можем загружать ресурсы, расположенные в «/ src/test/resources» в Java-коде, в частности, в модульных тестах. Рассмотрим стандартную структуру проекта maven. – Bhavesh

2
ClassLoader loader = Thread.currentThread().getContextClassLoader(); 
InputStream is = loader.getResourceAsStream("test.csv"); 

Если вы используете контекст ClassLoader для поиска ресурса, то определенно это будет стоить производительности приложения.

+1

Программисты всегда должны заботиться о производительности. В то время как преждевременной оптимизации, безусловно, следует избегать, зная, что более эффективный подход к работе всегда хорош. Это как знать разницу между LinkedList и ArrayList и когда использовать тот или иной. – Marvo

+3

@Marvo: Программисты всегда должны заботиться о качестве, возможностях и простоте обслуживания, производительность находится в очереди. –

0

Следующий класс может быть использован для загрузки resource из classpath, а также получить сообщение об ошибке установки в случае возникновения проблемы с данным filePath.

import java.io.InputStream; 
import java.nio.file.NoSuchFileException; 

public class ResourceLoader 
{ 
    private String filePath; 

    public ResourceLoader(String filePath) 
    { 
     this.filePath = filePath; 

     if(filePath.startsWith("/")) 
     { 
      throw new IllegalArgumentException("Relative paths may not have a leading slash!"); 
     } 
    } 

    public InputStream getResource() throws NoSuchFileException 
    { 
     ClassLoader classLoader = this.getClass().getClassLoader(); 

     InputStream inputStream = classLoader.getResourceAsStream(filePath); 

     if(inputStream == null) 
     { 
      throw new NoSuchFileException("Resource file not found. Note that the current directory is the source folder!"); 
     } 

     return inputStream; 
    } 
} 
19

Вот один быстрое решение с использованием Guava:

import com.google.common.base.Charsets; 
import com.google.common.io.Resources; 

public String readResource(final String fileName, Charset charset) throws IOException { 
     return Resources.toString(Resources.getResource(fileName), charset); 
} 

Использование:

String fixture = this.readResource("filename.txt", Charsets.UTF_8) 
-1

я заставить его работать без каких-либо ссылок на "класс" или "ClassLoader" ,

Предположим, у нас есть три сценария с указанием места файла.Файл»и рабочий каталог (где ваше приложение выполняет) является домом/MyDocuments/программы/проекты/MyApp:

а) подпапку потомка к рабочему каталогу: MYAPP/RES/файлы/example.file

б) подпапка не потомок в рабочем каталог: проектов/файлы/example.file

b2) Другая подпапка не потомок в рабочем каталог: программы/файлы/example.file

c) Корневая папка: главная/mydo cuments/files/example.file (Linux; в Windows, заменить домашний/с C :)

1) Получить правильный путь: а) String path = "res/files/example.file"; б) String path = "../projects/files/example.file" b2) String path = "../../program/files/example.file" с) String path = "/home/mydocuments/files/example.file"

В принципе, если это корневой каталог, начало имя пути с ведущей косой чертой. Если это подпапка, не должно быть косой черты перед именем пути. Если подпапка не является потомком к рабочему каталогу, к которому вы должны подключиться, используя «../». Это говорит системе, чтобы перейти в одну папку.

2) Создать объект File, передавая правильный путь:

File file = new File(path); 

3) Вы теперь хорошо идти:

BufferedReader br = new BufferedReader(new FileReader(file)); 
0

getResource() работает нормально с файлами ресурсов, размещенных в src/main/resources только. Чтобы получить файл, который находится на пути, отличном от src/main/resources, скажите src/test/java, вам нужно создать его неявно.

следующий пример может помочь вам

import java.io.BufferedReader; 
import java.io.FileReader; 
import java.io.IOException; 
import java.net.URISyntaxException; 
import java.net.URL; 

public class Main { 
    public static void main(String[] args) throws URISyntaxException, IOException { 
     URL location = Main.class.getProtectionDomain().getCodeSource().getLocation(); 
     BufferedReader br = new BufferedReader(new FileReader(location.getPath().toString().replace("/target/classes/", "/src/test/java/youfilename.txt"))); 
    } 
} 
10

Попробуйте Измельчитель коду на весеннем

ClassPathResource resource = new ClassPathResource("fileName"); 
InputStream inputStream = resource.getInputStream(); 

Или о неприменении весеннего проекте

ClassLoader classLoader = getClass().getClassLoader(); 
File file = new File(classLoader.getResource("fileName").getFile()); 
InputStream inputStream = new FileInputStream(file); 
+0

Если входной поток не будет закрыт? – 030

3

Теперь я иллюстрирующий исходный код чтение шрифта из каталога созданных ресурсов maven,

экр/главная/ресурсы/calibril.ttf

enter image description here

Font getCalibriLightFont(int fontSize){ 
    Font font = null; 
    try{ 
     URL fontURL = OneMethod.class.getResource("/calibril.ttf"); 
     InputStream fontStream = fontURL.openStream(); 
     font = new Font(Font.createFont(Font.TRUETYPE_FONT, fontStream).getFamily(), Font.PLAIN, fontSize); 
     fontStream.close(); 
    }catch(IOException | FontFormatException ief){ 
     font = new Font("Arial", Font.PLAIN, fontSize); 
     ief.printStackTrace(); 
    } 
    return font; 
} 

Он работал для меня, и надеюсь, что весь исходный код также поможет вам, Enjoy!

0

Просто используйте InputStream InputStream = ClassLoader.getSystemResourceAsStream ("XMLs/employee.xml")

Здесь есть папка XMLs, имеющий файлы employee.xml.

Смежные вопросы