This question already has answers here:
Reading a plain text file in Java
(31 answers)
Closed 2 years ago.
My project structure is like this:
Project
App
x.java
files
file.txt
main.java
I want to access file.txt via x.java.. My code:
File file = new File("file.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine())
out += sc.nextLine();
if (out.isEmpty()) out = "NOTHING";
but gives me NullPointerException.
If this file is supposed to be part of your app the way class files are (so, effectively read-only, an asset that you pack in with the rest. Think texture maps for games, or icons for user interfaces), use getResourceAsStream, as the resource in question may not even be a file (java projects tend to ship as jars, and an entry in a jar is not a file!).
If not, well, then figure out a way to get the full path info into your code, because it's not going to magically figure out that you have a dir structure with "App" and "files", which is non-standard. (the standard route is src/main/java/pkgname/Type.java for java files, and src/main/resources/pkgname/open.png for assets that just need to be there (don't need compiling).
If you set up a project in your favourite IDE according to this structure and configured using e.g. maven or gradle, then getResourceAsStream works during dev time, and also at runtime, even if the resource is inside the jar.
Basically when you read the file "file.txt", you don't provide with an absolute path so the operating system will look for a file in the current directly. That is the one where your program started.
I get you didn't start the program in the folder "files" but in another folder like maybe the folder "Project". In that case the path to use would be "files/file.txt".
I solved it !
First, I used
File directory = new File("./");
System.out.println(directory.getAbsolutePath());
to detect the whole path.. Then I appended the directory.getAbsolutePath() with the filename so it becomes directory.getAbsolutePath()+"file.txt"
I used the normal way to read a file by using the scanner and scanner.readLine() to read the file !
This answer
Has helped me
Related
I want to use image files for my java program, and for that I need File objects. But I have the problem that when I build my project, the project name has a .jar at the end of the name, making a File object like new File("..\\Project\\src\\ImageDirectory\\Image.png") useless, since the directory doesn't exist.
I've found out I could tecnically iterate through all the directorys on the computer but I don't want to do that because that could take some time with high amounts of directories and harddrives.
So, is there a reliable and easy way to get the directory the jar file is currently in?
My IDE is InellijIDEA
You can use Path to do this:
Path path = Paths.get(YourMainClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
Path have several methods to get more information.
For example, i have this JAR in Desktop and i am printing this:
System.out.println(path);
System.out.println(path.getRoot());
System.out.println(path.getParent());
The results are:
java -jar C:\Users\gmunozme\Desktop\Test.jar
C:\Users\gmunozme\Desktop\Test.jar
C:\
C:\Users\gmunozme\Desktop
Check that out,
Hope you can use it.
I'm trying to read a txt file that is in a folder called "levels". The class where I'm using the Scanner is in src/anotherPackageName, if that's relevant. When I execute:
Scanner s = new Scanner(new File("levels/level0")); //adding .txt doesn't fix
it throws an exception. I don't want to use an absolute path, but rather relative to the project if possible. This is my folder structure:
D:\OneDrive\Folder\AnotherFolder\ProjectName
ProjectName
src
packageOne
ClassWhereImUsingScanner
OtherClasses
(...)
levels
level0
level1
(...)
So in order to access a file you could do something like this:
FileReader sourceFile = new FileReader("levels/level0.txt");
BufferedReader inStream = new BufferedReader(sourceFile);
String Line = inStream.readLine();
Then, you can use a tokenizer depending on your data and how you want to store it.
You could see this example: http://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/
Bear in mind that in most Java code, the end state of the project is not run from the IDE, but rather from some production system (e.g. an app or a server). In that case, your development source code structure won't be available.
There are two main ways to read text files or other resources in Java: either you can find the path to the actual file, in which case you need to deal with possibly not running out of your development source tree, or else you need to find a way to bundle the text file into your project.
Most Java projects end up getting compiled into some kind of archive, either a JAR file or a WAR file (for web applications) or something like an Android APK. In most cases you can add your own text files into the project archive. (For example, in a Maven project, if you just put your text file in the src/main/resources folder it should be included in the compiled JAR.)
However, in this case, the text file is no longer a separate file on disk, but rather a blob of data inside an archive. You could unzip the archive to get an actual File object, but that's wasteful if all you actually need is to read the bytes.
Thus, the most common way that text files like this are read is by using the existing ClassLoader mechanism, which is what is reading the .class files from disk (or from an archive, or over the network, or whatever). The ClassLoader already knows how to load bytes that are "alongside" your compiled code, so you can just make use of that.
In your case, you should be able to do something like this:
Scanner scanner = new Scanner(
getClass().getResourceAsStream("/path/to/file.txt"));
In this case, the /path/to/file.txt path is relative to the path your class was loaded from. E.g. if your class is named my.package.Foo then the actual class bytes will be in a folder (either a filesystem folder or in a JAR file or something) named my/package/Foo.class -- in this case, the path/to/file.txt and my/package/Foo.class will be relative to the same root.
See the documentation on resources for more information.
Usually the path is relative to your execution, but it also depends on your project setup on eclipse, could you send more information about you directory structure?
Based on you structure try something like this:
Scanner s = new Scanner(new File("../levels/level0"));
This question already has answers here:
Reading a resource file from within jar
(15 answers)
Closed 6 years ago.
I built a game a while ago in eclipse. I wanted to export it like usual to a .jar. I've done this before and with my other projects it works. This one doesn't work because it gives a blank white screen. I put in a System.exit(1) on a different spots to see where the program stops working. Eventually I found the spot. It can't seem to locate my .txt file but in eclipse if does work. I've checked the .jar with 7zip(like winzip) and the .txt file is in there. I also used the command line to open it and it gives the same error of not being able to locate the .txt file. I've looked a lot on the internet and stackflow for people that have same questions of related problems but they didn't offer a fix unfortunately.
The code that make a new world is this.
world = new World(handler,"res/worlds/world1.txt");
In the world it calls this funtion:
loadWorld(path);
This funtion should return back a string. First it calls another function to get that string:
String file = Utils.loadFileAsString(path);
Finally this is the code that doesn't work because the file can't be located.
public static String loadFileAsString(String path){
StringBuilder builder = new StringBuilder();
try{
BufferedReader br = new BufferedReader(new FileReader(path));
String line;
while((line = br.readLine()) != null)
builder.append(line + "\n");
br.close();
}catch(IOException e){
e.printStackTrace();
}
return builder.toString();
}
Is there something that I missed? Eclipse runs it fine but after exporting its like the .txt isn't exported but it is still there.
Thanks in advance.
The java class File (which is used by FileReader) operates on OS the file system path, either absolute, or relative to the current working directory. Your example denotes a relative path. I beg "res/world/..." is just beyond your project folder in eclipse. When running an app in eclipse the current directory is the project path itself. Therefore your code worked in eclipse.
Running standalone (by starting a jar) the file cannot be found in the same OS path. It is located within the jar. Therefore you must access it by using the resource loading features of your classloader.
That is a relative path. Relative paths are resolved relative to where you are when you execute the application. In eclipse this is, by default, the project directory. However, if you are running the jar externally, it will depend entirely on how you run the jar.
One common solution is to always have the jar placed in the same location relative to the resource (world1.txt). For example, the following directory structure...
-lib
--main.jar
-res
--worlds
---world1.txt
main.sh
Then, you need to get some base directory into your application. One way is to pass in the absolute path to main.jar as a command line argument, system property, or environment variable.
Another common approach is to get the path of the running jar file using some technique like this.
Finally, in your application, instead of using a relative path, you can use an absolute path:
String world1Path = baseDirectory + "res/worlds/world1.txt"
If you have an archive reader (such as 7zip) open up the .jar and see if your .txt file is inside the .jar. If not, simply copy the .txt file into the .jar file. This happened to me when trying to use a .png for a Java application. Hope it works out!
This question already has answers here:
How to read text file from classpath in Java?
(17 answers)
Closed 7 years ago.
I have a very simple method which uses the getclass().getResourceAsStream() method to read a file. However it always returns null and I can't figure out what is wrong. Here is my piece of code.
InputStream sw = getClass().getResourceAsStream("/filename.txt");
BufferedReader bf = new BufferedReader( new InputStreamReader(sw));
sw always remain null. the file filename.txt exist in the root directory of my project.
EDIT:
I found the reason. I realized that I was running my project from Eclipse and the project was not part of the classpath on my PC. However if I package my program as a jar file and then run it, the files in the jar file are considered as resources and can be read using the getResourceAsStream() method.
The method Class.getResourceAsStream() looks for the designated resource within the Java class path, not based on the project root.
The project root usually is not part of the classpath. Instead, you should have a src folder (or a similar name), which contains the Java files and may also contain your text file. Or, if you use Maven, you have folders src/main/java and src/main/resources, which are classpath roots. In this case, the text file should reside in the resources folder.
If your project gets packaged into a .jar file, all its resources are packaged in the .jar file along with the .class files, and will be found by Class.getResourceAsStream().
Root of your project is not always the root of the path from the ClassLoader point of view.
Easiest way to find out where it is trying to load the resource from:
System.out.println(MyClass.class.getResource("/").getPath());
And after that you may be able to easily find out the part of the project or run configuration that causes the difference between your assumption and the reality about the right placement of the file.
getResourceAsStream() reads a resource file, ie a file into .jar file (or resource directory), not a regular file in working directory on disk. Use FileReader to read a file from disk
user likewise,
InputStream sw = this.class.getClassLoader().getResourceAsStream("filename.txt");
Note : filename.txt file should be present on classpath.
Just to be complete, here's a simple test that does print out the absolute path of a resource. You can use this inside any class to find the location of that class on your hard drive, in case it isn't obvious what your build system is doing. Just substitute the name ErrorTest for the class you are checking.
public class ErrorTest
{
public static void main(String[] args )
{
final String className = ErrorTest.class.getSimpleName().replace( '.', '/').concat(".class");
System.out.println(ErrorTest.class.getResource(className).getPath() );
}
}
Output of this program:
run:
/C:/Users/Brenden/Google%20Drive/proj/tempj8/build/classes/quicktest/ErrorTest.class
BUILD SUCCESSFUL (total time: 0 seconds)
I am doing some algorithmic problems on the website USACO, and for every submission they want us to make two files for input and output to test values. So if the problem was called "test", they would want users to make the files "test.in" and "test.out" which requires them to change their extensions to ".out" and ".in". How do I change their extensions from ".txt" to ".in" or ".out"?
Note: I am using Windows 8
Thank you
To make Java read files in Eclipse
One must make sure that the words typed in the code and in the name of the file match each other.
For example: The file referenced in must exist.
BufferedReader f = new BufferedReader(new FileReader("test.in"));
Also, you have to make the file under the project folder (in Eclipse or manually in Windows Explorer) because that folder is the directory at for that code, and if it is not in the folder the code will not be able to read it. You can also right-click the project to import files into the folder.
My reference: Trial and Error
http://www.coderanch.com/t/439615/java-io/java/Eclipse-won-read-text-file