Comment charger un fichier à partir du dossier de ressources?


240

Mon projet a la structure suivante:

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

J'ai un fichier dans /src/test/resources/test.csvet je veux charger le fichier à partir d'un test unitaire dans/src/test/java/MyTest.java

J'ai ce code qui n'a pas fonctionné. Il se plaint "Aucun fichier ou répertoire de ce type".

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

J'ai aussi essayé

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

Cela ne fonctionne pas non plus. Il revient null. J'utilise Maven pour construire mon projet.


Ça ne marche pas comment? Quelle est ton erreur?
Daniel Kaplan

17
essayez cecithis.getClass().getResource("/test.csv")
SRy


@SRy, cela a fonctionné (car cela donnera l'URL du chemin absolu en retour), mais au moment où je crée un fichier jar, cela ne fonctionne pas, car il se trouve dans un bocal et le chemin absolu devient invalide, existe-t-il un moyen de jouer avec le chemin relatif lui
ShankPossible

Réponses:


240

Essayez le suivant:

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

Si ce qui précède ne fonctionne pas, divers projets ont été ajoutés à la classe suivante: 1 (code ici ). 2ClassLoaderUtil

Voici quelques exemples d'utilisation de cette classe:

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
}

Remarques

  1. Voyez-le dans The Wayback Machine .
  2. Également dans GitHub .

14
merci pour la réponse, pourriez-vous expliquer pourquoi nous devrions utiliser ce chargeur très spécifique mais pas celui de la classe?
Hui Wang

1
génial, je suis tellement stupide que j'utilisais Object.class.getClassLoader();, à partir d'un contexte statique qui ne fonctionnait pas - cette suggestion fait - enfin presque, elle injecte %20pour les espaces qui me donneFileNotFoundException
ycomp

5
@ycomp Parce que getResource renvoie une URL, pas un fichier. La méthode getFile de java.net.URL ne convertit pas une URL en fichier; il renvoie simplement le chemin et les parties de requête de l'URL. Vous ne devriez même pas essayer de le convertir en fichier; appelez simplement openStream et lisez à partir de cela.
VGR

Vérifiez ce projet, résout l'analyse des dossiers de ressources: github.com/fraballi/resources-folder-scanner
Felix Aballi

60

Essayer:

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

IIRC getResourceAsStream()par défaut est relatif au package de la classe.

Comme l'a noté @Terran, n'oubliez pas d'ajouter le /au début du nom de fichier


3
Pour ceux qui recherchent la raison, ce message vous apporte tout le chemin pour obtenir la ressource en tant que String stackoverflow.com/a/35446009/544045
Trevor

12
Le "/" est la clé.
Terran

33

Voici une solution rapide avec l'utilisation de la goyave :

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);
}

Usage:

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

28

Essayez les codes fluides sur le projet Spring

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

Ou sur un projet non printanier

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

Le InputStream ne doit-il pas être fermé?
030

7

Projet non printanier:

String filePath = Objects.requireNonNull(MyClass.class.getClassLoader().getResource("any.json")).getPath();

Stream<String> lines = Files.lines(Paths.get(filePath));

Pour les projets Spring, vous pouvez également utiliser un code de ligne pour obtenir n'importe quel fichier dans le dossier de ressources:

File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "any.json");

String content = new String(Files.readAllBytes(file.toPath()));

5

Maintenant, j'illustre le code source pour lire une police à partir du répertoire de ressources créé par maven,

scr / main / resources / calibril.ttf

entrez la description de l'image ici

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;
}

Cela a fonctionné pour moi et j'espère que le code source entier vous aidera également, profitez-en!


5

Pour java après 1.7

 List<String> lines = Files.readAllLines(Paths.get(getClass().getResource("test.csv").toURI()));

Je dois utiliser "/test.csv" (notez la barre oblique).
Leon

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

Si vous utilisez ClassLoader contextuel pour trouver une ressource, cela coûtera certainement les performances de l'application.


4
Les programmeurs doivent toujours se soucier des performances. Bien qu'une optimisation prématurée soit certainement à éviter, connaître l'approche la plus efficace à adopter est toujours une bonne chose. C'est comme connaître la différence entre LinkedList et ArrayList et quand utiliser l'un ou l'autre.
mars 2015

6
@Marvo: Les programmeurs doivent toujours se soucier de la qualité, des capacités et de la facilité de maintenance, les performances sont au rendez-vous.
Igor Rodriguez

2

Importez les éléments suivants:

import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;
import java.util.ArrayList;

La méthode suivante renvoie un fichier dans une ArrayList of Strings:

public ArrayList<String> loadFile(String filename){

  ArrayList<String> lines = new ArrayList<String>();

  try{

    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    InputStream inputStream = classloader.getResourceAsStream(filename);
    InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
    BufferedReader reader = new BufferedReader(streamReader);
    for (String line; (line = reader.readLine()) != null;) {
      lines.add(line);
    }

  }catch(FileNotFoundException fnfe){
    // process errors
  }catch(IOException ioe){
    // process errors
  }
  return lines;
}

2

J'ai fait face au même problème .

Le fichier n'a pas été trouvé par un chargeur de classe, ce qui signifie qu'il n'a pas été compressé dans l'artefact (jar). Vous devez construire le projet . Par exemple, avec maven:

mvn clean install

Ainsi, les fichiers que vous avez ajoutés au dossier de ressources entreront dans la construction maven et deviendront disponibles pour l'application.

Je voudrais garder ma réponse: elle n'explique pas comment lire un fichier (d'autres réponses l'expliquent), elle répond pourquoi InputStream ou resourceétait nulle . Une réponse similaire est ici .


1
Merci, ça m'a évité de penser que je perdais la tête!
StuPointerException

1

getResource () fonctionnait bien avec les fichiers de ressources placés src/main/resourcesuniquement. Pour obtenir un fichier qui se trouve sur le chemin autre que src/main/resourcesdire, src/test/javavous devez le créer exlicitement.

l'exemple suivant peut vous aider

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")));
    }
}

0

Le code fonctionne-t-il lorsque vous n'exécutez pas le pot Maven-build, par exemple lors de l'exécution à partir de votre IDE? Si c'est le cas, assurez-vous que le fichier est réellement inclus dans le bocal. Le dossier des ressources doit être inclus dans le fichier pom, dans <build><resources>.


Lorsque vous utilisez eclipse et exécutez du code à partir d'IDE lui-même. Comment pouvons-nous charger des ressources situées dans "/ src / test / resources" dans le code Java spécifiquement dans les tests unitaires. Considérons une structure de projet maven standard.
Bhavesh

0

La classe suivante peut être utilisée pour charger un resourcedepuis le classpathet recevoir également un message d'erreur approprié en cas de problème avec le donné 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;
    }
}

0

J'ai résolu ce problème en ajoutant un /scr/main/resourcesdossier à monJava Build Path

entrez la description de l'image ici


essayez ceci mais ce n'est pas la solution
Jasonw

0

Je l'ai fait fonctionner à la fois sur le pot en cours d'exécution et dans l'IDE en écrivant comme

 InputStream schemaStream = ProductUtil.class.getClassLoader().getResourceAsStream(jsonSchemaPath);
            byte[] buffer = new byte[schemaStream.available()];
            schemaStream.read(buffer);

        File tempFile = File.createTempFile("com/package/schema/testSchema", "json");
        tempFile.deleteOnExit();
        FileOutputStream out = new FileOutputStream(tempFile);
        out.write(buffer);

À quoi ressemble la structure de vos fichiers?
luckydonald


0

Vous pouvez utiliser com.google.common.io.Resources.getResource pour lire l'url du fichier, puis obtenir le contenu du fichier à l'aide de java.nio.file.Files pour lire le contenu du fichier.

URL urlPath = Resources.getResource("src/main/resource");
List<String> multilineContent= Files.readAllLines(Paths.get(urlPath.toURI()));

-2

Je le fais fonctionner sans aucune référence à "class" ou "ClassLoader".

Disons que nous avons trois scénarios avec l'emplacement du fichier 'example.file' et votre répertoire de travail (où votre application s'exécute) est home / mydocuments / program / projects / myapp:

a) Un sous-dossier descendant vers le répertoire de travail: myapp / res / files / example.file

b) Un sous-dossier non descendant vers le répertoire de travail: projets / fichiers / exemple.fichier

b2) Un autre sous-dossier non descendant du répertoire de travail: programme / fichiers / exemple.fichier

c) Un dossier racine: home / mydocuments / files / example.file (Linux; sous Windows remplacez home / par C :)

1) Obtenez le bon chemin: a) String path = "res/files/example.file"; b) String path = "../projects/files/example.file" b2) String path = "../../program/files/example.file" c)String path = "/home/mydocuments/files/example.file"

Fondamentalement, s'il s'agit d'un dossier racine, démarrez le nom du chemin avec une barre oblique. S'il s'agit d'un sous-dossier, aucune barre oblique ne doit précéder le nom du chemin. Si le sous-dossier n'est pas descendant vers le répertoire de travail, vous devez y accéder en utilisant "../". Cela indique au système de remonter d'un dossier.

2) Créez un objet File en passant le bon chemin:

File file = new File(path);

3) Vous êtes maintenant prêt à partir:

BufferedReader br = new BufferedReader(new FileReader(file));
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.