Kaloyan Roussev
Kaloyan Roussev

Reputation: 14711

How can I open a file without specifying the absolute directory?

I have a file which is located in my project directory:

src/test/resources/250.csv

This is the code that needs it:

CSVReader reader = new CSVReader(new FileReader(FILE_PATH));

FILE_PATH should be a String

How do I turn this path:

final String FILE_PATH = "C:\\Users\\Kowalski\\Desktop\\test-master\\test1\\src\\test\\resources\\250.csv"

into something more reliable and relative?

I need to be able to run my code on Windows and Linux and move this resource file along with the project, so I don't have to specify absolute paths to reach it, but paths relative to my project instead.

I read this question about it, but couldn't apply it to my case: Absolute Path of Project's folder in Java

EDIT: I have 4 weeks of experience and I consider myself really new to the language

EDIT: This is the accepted answer's solution:

final String FILE_PATH = "src/test/resources/250.csv";

Upvotes: 2

Views: 15404

Answers (8)

G33K_C0D3R
G33K_C0D3R

Reputation: 67

URL fileURL= yourClassName.class.getResource("yourFileName.extension");
String myURL= fileURL.toString();

now you don't need long path name PLUS this one is dynamic in nature i.e., you can now move your project to any pc, any drive.
This is because it access URL by using your CLASS location not by any static location (like c:\folder\ab.mp3, then you can't access that file if you move to D drive because then you have to change to D:/folder/ab.mp3 manually which is static in nature)
(NOTE: just keep that file with your project)

You can use fileURL as: File file=new File(fileURL.toURI());
You can use myURL as: Media musicFile=new Media(myURL); //in javaFX which need string not url of file

Upvotes: 0

rocketboy
rocketboy

Reputation: 9741

You can use getResource/AsResource both work with paths relative to classloader.

getclassLoader().getResourceAsStream(relativePath)
getclassLoader().getResource(relativePath)

The path should be relative to classpath root of the classloader. You can look on SO and here for documentation.

You can also look at another variant which works with path relative to .class.

class.getResourceAsStream(relativePath)
class.getResource(relativePath)

Sample Code:

//As file
URL loc = this.class.getclassLoader().getResource("250.csv");
File f = new File(loc.getPath());
//As Stream
InputStream loc = this.class.getclassLoader().getResourceAsStream("250.csv");
InputStreamReader in = new InputStreamReader(loc);

Assuming files in src/test/resources/ are on your classpath.

Upvotes: 2

mokuril
mokuril

Reputation: 772

This is how you can get your project root path:

String path = System.getProperty("user.dir");

EDIT: I misread your requirements:

getClass().getClassLoader().getResourceAsStream("yourFileName");

Upvotes: 0

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136002

This path src/test/resources/250.csv suggests that this is a Mavne project. If this is the case then this file is a resource that will get into project jar at root level and can be read as this

CSVReader reader = new CSVReader(new InputStreamReader(getClass().getResourceAsStream("250.csv")));

Upvotes: 0

khachik
khachik

Reputation: 28693

Any relative path will be joined to the current directory when running your code. So if you run your code from your project directory, you can put FILE_PATH = "src/test/resources/250.csv". Alternatively, you can calculate the location of the csv file relative to your class/jar file.

But the most correct thing to do in this case is to pass the file path as a command-line argument:

// ...
public static void main(String [] args) {
    // if args.length != 1 display some useful message and exit
    String filePath = args[1];
    CSVReader reader = new CSVReader(new FileReader(filePath));
    // ...
}
// ...

Upvotes: 2

Pace
Pace

Reputation: 43817

Relative paths in Java are relative to the place the user was in when they executed the command. This makes a lot of sense for some things (e.g. shell commands) but not others. Two standard alternative approaches jump to my mind for dealing with this problem (although I am sure there are many more).

  • Put the resource on the classpath

If your resource is a part of your application and the user does not need to see or edit the resource, then you can simply put it on the classpath (in Maven src/main/resources is automatically added to the classpath and files there are bundled into the JAR so they will be on the classpath when deployed) and then load it using Class.getResource().

  • Create a user data directory

Create a directory for storing user files (e.g. ~/.appname) and create a utility class for saving and loading files to that data directory and initializing that directory on startup if it doesn't exist. Then your code won't be cluttered with long absolute paths, and your application will be portable.

Upvotes: 4

Frank Olschewski
Frank Olschewski

Reputation: 500

You should use a resource loader:

this.getClass().getClassLoader().getResourceAsStream("250.csv");

Upvotes: 0

Qwerky
Qwerky

Reputation: 18435

Have a look at ClassLoader's getResource(String name) method. It will try and find the named resource in the classpath. Assuming you are using maven, anything in src/main/resources will be on the classpath and will get found.

Upvotes: 0

Related Questions