Trying to practice Java by doing basic functionality like reading input.
I am trying to parse movies-sample.txt found in:
C:\University\BigDataManagement\Data-Mining\hw1\src\main\resources\movies-sample.txt
Trying to reach movies-sample.txt from
C:\University\BigDataManagement\Data-Mining\hw1\src\main\java
\univ\bigdata\course\MoviesReviewsQueryRunner.java
Using the answer found here on how to parse a large file line by line.
File file = new File("../../../../../resources/movies-sample.txt");
I am getting the following error:
The system cannot find the path specified
Given the above two paths, what am I doing incorrect?
If it's a web app then the resources folder is your root element, otherwise it will be the src folder as mentioned in comments.
In your case here as you are writing a standalone Java program and as your file is loacted in the resources folder, you can use CLassLoader to read the file as a stream.
This is how should be your code:
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream is = classloader.getResourceAsStream("movies-sample.txt");
Then you will be able to read the is stream line by line.
If you run your program directly from command line, then the path must be related to your current directory.
If you run your program from an IDE, then the current directory of the runnin program depends on the IDE and the way it is configured.
You can determine what is the current directory with System.getProperty("user.dir")
Whatever, hard coding a path in an application is always a bad thing because you cannot ensure where the run was launched from. Either:
it is a user resource, then its path must be input in some way (open... in GUIs apps)
it is a resource needed by the app to run correctly and it should be embedded in some way into the app itself (look for Resource Bundle)
it is a kind of optional external resource (config file for example, or path specified in a config file) and its location should be computed in some way.
Related
I have a maven project with these standard directory structures:
src/main/java
src/main/java/pdf/Pdf.java
src/test/resources
src/test/resources/files/x.pdf
In my Pdf.java,
File file = new File("../../../test/resources/files/x.pdf");
Why does it report "No such file or dirctory"? The relative path should work. Right?
Relative paths work relative to the current working directory. Maven does not set it, so it is inherited from whatever value it had in the Java process your code is executing in.
The only reliable way is to figure it out in your own code. Depending on how you do things, there are several ways to do so. See How to get the real path of Java application at runtime? for suggestions. You are most likely looking at this.getClass().getProtectionDomain().getCodeSource().getLocation() and then you know where the class file is and can navigate relative to that.
Why does it report "No such file or dirctory"? The relative path should work. Right?
wrong.
Your classes are compiled to $PROJECT_ROOT/target/classes
and your resources are copied to the same folder keeping their relative paths below src/main/resources.
The file will be located relative to the classpath of which the root is $PROJECT_ROOT/target/classes. Therefore you have to write in your Pdf.java:
File file = new File("/files/x.pdf");
Your relative path will be evaluated from the projects current working directory which is $PROJECT_ROOT (AFAIR).
But it does not matter because you want that to work in your final application and not only in your build environment. Therefore you should access the file with getClass().getResource("/path/to/file/within/classpath") which searches the file in the class path of which the root is $PROJECT_ROOT/target/classes.
No the way you are referencing the files is according to your file system. Java knows about the classpath not the file system if you want to reference something like that you have to use the fully qualified name of the file.
Also I do not know if File constructor works with the classpath since it's an abstraction to manage the file system it will depend where the application is run from. Say it is run from the target directory at the same level as source in that case you have to go one directory up and then on src then test the resources the files and finally in x.pdf.
Since you are using a resources folder I think you want the file to be on the classpath and then you can load a resource with:
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("<path in classpath>");
Then you can create a FileInputStream or something to wrap around the file. Otherwise use the fully qualiefied name and put it somewere like /home/{user}/files/x.pdf.
I've got a project to do with 2 other classmates.
We used Dropbox to share the project so we can write from our houses (Isn't a very good choice, but it worked and was easier than using GitHub)
My question is now about sharing the object stream.
I want to put the file of the stream in same dropbox shared directory of the code.
BUT, when i initialize the file
File f = new File(PATH);
i must use the path of my computer (C:\User**Alessandro**\Dropbox)
As you can see it is linked to Alessandro, and so to my computer.
This clearly won't work on another PC.
How can tell the compiler to just look in the same directory of the source code/.class files?
You can use Class#getResource(java.lang.String) to obtain a URL corresponding to the location of the file relative to the classpath of the Java program:
URL url = getClass().getResource("/path/to/the/file");
File file = new File(url.getPath());
Note here that / is the root of your classpath, which is the top of the directory containing your class files. So your resource should be placed inside the classpath somewhere in order for it to work on your friend's computer.
Don't use absolute paths. Use relative paths like ./myfile.txt. Start the program with the project directory as the current dir. (This is the default in Eclipse.) But then you have to ensure that this both works for development and for production use.
As an alternative you can create a properties file and define the path there. Your code then only refers to a property name and each developer can adjust the configuration file. See Properties documentation.
I am pretty new to Maven, and having some trouble reading files. Specifically, my program takes the absolute path of a file as input from the user, and then parses it. Unfortunately I am unclear on how to get my application to read a file as input from an arbitrary location.
Before I started using maven on the project, I used this code successfully:
String absolutePath = "/Users/akhalsa/path/to/file.txt";
inputStream = new BufferedReader(new FileReader(absolutePath));
However, since migrating to maven, this seems to have stopped working. From what I have read in maven I should use
InputStream in = getClass().getResourceAsStream(filePath);
Where filePath seems to be the relative path of the file in question. Does getResourceAsStream require that the file being read be inside the jar? Can this file be an external file's absolute path? When I use an absolute path here it says "Resource not found".
This must be a common problem in terms of letting users input a file from the file system for a maven application to process. What is the best way to this?
Thanks in advance.
getResourceAsStream() finds the resource on a path known to the jvm, so you can't load arbitrary files.
Maven does no magic trickery so if you are using actual absolute paths, the code should keep on working.
The "Users" part of the path reminds me of windows, but the path is not a valid windows path so are you sure you are passing along a valid absolute path?
I have following code block in my application;
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(FilePath);
Here 'FilePath' is an absolute path of the file.
Above code works fine in linux and in windows when i run the application in normal mode.(ie: in command prompt)
But this is NOT working, when I run the application as a windows service. I get input stream as 'null'.
Anyone encountered such issue before? I could not find any information regarding this other than java classloaders . Here we use "ContextClassLoader", which is the right classloader to be used..
Any clue on this?
I think this happens because you have "." (the current folder) on the classpath. That is a) a bad idea and b) makes your app break in odd ways.
What you need to understand is the difference between a file and a resource. A file is something outside of the classpath.
You should use File and FileReader to access them.
A resource is something on the classpath. Paths for resources always use / as file separator and not File.separator.
Another way to fix this is to add $HOME/repository/ (Linux) or %HOME%/repository/ to the classpath and load the resource using "resources/api_templates/api.xml". for this to work, resources must be a folder in $HOME/repository/.
If you don't do this, then all files in your home directory (or whatever directory you happen to start the application in) are added as resources to the classpath.
I have a small problem calling a path(that has the python file, that I need to run) in the following code:
Process p = Runtime.getRuntime().exec(callAndArgs,env,
new java.io.File("C:\\Users\\Balkishore\\Documents\\NetBeansProjects\\Testinstrument_Rest\\build\\web"));//excuting python file
As it can be seen from the above code, the python file is called using the path specified in java.io.file function. But it is very specific, as it can be run only in my computer. How can i make it generic, so that it is possible to run this piece of code in any computer?
Any help would be very much appreciated.
Put your python script to the location relative to your working directory and use relative path. Alternatively use configuration file or property to read the path from.
If this file is already exist in the app then you need to do
ServletContext.getRealPath("/");
which will give you the path to web root now from here you need to move relatively to reach to your file
If this is an external file
put it in ${user.home}/appname/
String filePath = System.getProperty("user.home")+File.separator+"APP_NAME"
and instruct your users to put the file in this path, or read the path from some configuration file (.properties, .conf)