Access file from another package - java

My situation is as following : I have package packA where I have classA, and I have a file.txt in packB.resources. In classA I'm using this to access file.txt :
InputStreamReader in = new InputStreamReader(new FileInputStream("/packB/resources/file.txt"), "UTF-8");
But unfortunately it shows me an exception :
java.io.FileNotFoundException : \packB\resources\file.txt (The
specified path was not found)

The FileInputStream class opens a file in the file system based on a file system path.
But what you are apparently trying to do is to open a resource located via the classpath. You should be using Class.getResourceAsStream(String).

If your file.txt is packaged with application you should not access using file system at all. The application may be packaged into jar, so the file is not located in file system. You should access it as a resource instead:
InputStreamReader in = new InputStreamReader(getClass().getResourceAsStream("/packB/resources/file.txt"), "UTF-8"));

Use something like the following. Note, the / used as a prefix before the package name. YourClass is assumed to be in packA.
InputStream stream = YourClass.class.getResourceAsStream("/packB/resources/file.txt");

You should remove the trailing / from the file path and use classA.class.getClassLoader().getResourceAsStream("packB/resources/file.txt").

Related

Why won't input stream find a file outside of the class folder

I want to want to use input stream with a file "NewFile.java", the code I have works fine if the file is situated in the same folder as the .class file that is performing the action. But once I move I get null reference.
I have tried using absolute and relative paths with and without a '/' at the start.
InputStream in = getClass()
.getResourceAsStream("NewFile.java");
I would like to source the file when it is located in the root directory of the project.
Better use InputStream in= new FileInputStream(new File("path/to/yourfile"));
The way you are using it now is as a resource which has to be in the class path.
getResourceAsStream() is not meant to open arbitrary files in the filesystem, but opens resource files located in java packages. So the name "/com/foo/NewFile.java" would look for "NewFile.java" in the package "com.foo". You cannot open a resource file outside a package using this method.
There is a distinction between files on the file system, and resources, on the class path. In general a .java source file won't be copied/added to the class path.
For a class foo.bar.Baz and a resource foo/bar/images/test.png one can use
Baz.class.getResourceAsStream("images/test.png")
Baz.class.getResourceAsStream("/foo/bar/images/test.png")
As you see the paths are class paths, possibly inside .jar files.
Use file system paths:
Path path = Paths.get(".../src/main/java/foo/bar/Baz.java");
InputStream in = Files.newInputStream(path);
List<String> lines = Files.readAllLines(path);
List<String> lines = Files.readAllLines(path, StandardCharsets.ISO_8859_1);
Files.copy(path, ...);

Jar is not loading resources file

I have a project with a folder "src/main/resources" where inside there is the hibernate configuration file, I load it using this line of code
HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()
From inside the IDE it is working well, but when I create the jar it doesn't file the file.
How can I load it properly in the jar file too?
Thanks
Could you please try this:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileName").getFile());
I cannot say for ceratin that this is the issue without knowing how exactly you use the path extracted by:
HibernateUtil.class.getResource("/hibernate.cgf.xml").getPath()
but I can tell you this:
Run from an IDE the above line of code will return:
/path/to/project/src/main/resources/hibernate.cgf.xml
which is a valid filesystem path. You can then use this path to, for example, create an instance of File class and then use that instance to read the file contents.
However the same line of code run from inside a jar file will return:
file:/path/to/jar/jar_name.jar!/hibernate.cgf.xml
which is not a valid filesystem path. If you create an instance of File class using this path and then try to read the contents of the file you'll get an exception: java.io.FileNotFoundExeption
To read the contents of the file from inside of a jar you should use method Class.getResourceAsStream(String), which will return an instance of class sun.net.www.protocol.jar.JarURLConnection.JarURLInputStream (or equivalent in non-Oracle or non-OpenJDK Java). You can then use this object to read the contents of the file. For example:
InputStream inputStream = HibernateUtil.class.getResourceAsStream("/hibernate.cgf.xml");
Scanner scanner = new Scanner(inputStream).useDelimiter("\\A");
String fileContents = scanner.hasNext() ? sscanner.next() : "";
Most likely, the file is absent from the jar you create. There's too little information in your question, but I will try a guess:
Your hibernate.cgf.xml resides in the same directory as the Java sourcefles, and you are using a build tool (be it IDE, maven, gradle or an ant script) that expects resources to be stored in a separate directory.
It's easy to check: try to unzip your jar and see if the file is there (use any tool, you can just change the extension from .jar to .zip). I think you will see the file is absent.
Then come back with a question: "how to pack my non-java resources into a jar, using XXX", where XXX will be the name of the techology you are using for building the jar.
Most probably the slash in "/hibernate.cgf.xml" is not needed, if the hibernate.cgf.xml is in the same package as you class HibernateUtil.
You can access the file actually also via the classloader using the full path. Yet you never add to it the first slash.
Here is some code demonstrating how you can access the file using different methods:
public static void main(String[] args) {
// Accessing via class
System.out.println(SimpleTests.class.getResource("hibernate.cgf.xml").getPath());
// Accessing via classloader from the current thread
String path = Thread.currentThread().getContextClassLoader()
.getResource("simple/hibernate.cgf.xml").getPath();
System.out.println(path);
// Accessing via classloader used by the current class
System.out.println(SimpleTests.class.getClassLoader().getResource("simple/hibernate.cgf.xml").getPath());
}
In the example above the package 'simple' should be replaced by the package where your hibernate.cgf.xml is. But you should never have the slash at the beginning of the package declaration.

FileNotFoundException while running as a jar

FileInputStream fstream = new FileInputStream("abc.txt")
is throwing a FileNotFoundExceptionn while running as a jar. Why ? Normally it is able to find while running from main method.
class MyClass{
InputStream fstream = this.getClass().getResourceAsStream("abc.txt");
}
This code should be used.
And the files(in this case abc.txt) should be kept , in the Object references class location. That means , this.getClass refers to the location of some folder i.e, com/myfolder/MyClass.java folder .
So we should keep the abc.txt in com/myfolder this location.
If your file is packaged with your jar then you should to get information using getClass().getResource(url):
FileInputStream inputStream =
new FileInputStream(new File(getClass().getResource(/path/to/your/file/abc.txt).toURI()));
Else you need to create it always in the same path with your jar and you can get it like you do :
src/myJar.jar
src/folder/abc.txt
FileInputStream fstream = new FileInputStream("folder/abc.txt");
You can read here also :
How do I load a file from resource folder? and File loading by getClass().getResource()
You can use FileInputStream only when you actually have a file on the computer's filesystem. When you package your text file in the jar file for your program, it is not a file in the filesystem. It is an entry inside the jar file.
The good news is that it is even easier, in Java, to access the file this way: it is in your classpath, so you can use getResourceAsStream().
InputStream stream = getClass().getResourceAsStream("abc.txt");
If you have your classpath set up correctly, this will work regardless of whether it is a file in a directory (such as during development), or an entry in a jar file (such as when released).
It's because your working directory will probably be different under the two environments. Try adding the line
System.out.println(new File("abc.txt").getAbsolutePath());
to see where it is actually looking for the file.

Include text file in Eclipse JAR export?

I am using a FileInputStream to read from a File object. My program is able to read the text file when run in the Eclipse IDE, but not when it is run as a JAR file.
I am exporting it as a JAR file and not a Runnable JAR file, and I know that the text file is already included in the JAR file because I extracted it to check.
This is what my file structure looks like:
I would suggest you to put your learnaboutfonts.txt inside src folder(not inside package) and read file in source code like the following:
Resource resource = new ClassPathXmlApplicationContext().getResource("classpath:learnaboutfonts.txt");
InputStream is = resource.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
And you can use br as you want to use. Happy Coding.
You should use something like:
InputStream input = getClass().getResourceAsStream("/learnaboutfonts.txt");
Note that the trick is using the leading "/" properly. If you don't put the leading /, then it searches for the file in the package of the class its invoked from.
How do you access your file? You maybe need a relative file path like "./mytext.txt").
Use this pattern:
InputStream is = new getClass().getResourceAsStream(
"/text.txt");
Test to include your text-file in your package of your class where you want to access the file.

Eclipse-Java: where to put file for Read purpose

I'm programming Java in Eclipse IDE. Here is code I want to read file:
File file = new File("file.txt");
reader = new BufferedReader(new FileReader(file));
I put file.txt in two place:
1) same folder of this SOURCE file.
2) in bin\...\ (same folder of this CLASS file)
But I allways receive NO FILE FOUND.
Please help me.
thanks :)
If the file ships with your application, it would be better accessed as a resource than as a file. Simply copy it to somewhere in your build path and use Class.getResourceAsStream or ClassLoader.getResourceAsStream. That way you'll also be able to access it if you bundle your app as a jar file.
Currently, you're looking for the file relative to the process's current working directory, which could be entirely unrelated to where the class files are.
if you put the file under sources and inside the package "test" for example, the path is:
./src/test/file.txt
you can use
File file = new File("./src/test/file.txt");
System.out.println(file.exists());
The path ./bin/test/file.txt will work in the second case and is more suitable for a normal java project

Categories