I have tried this in many ways, and followed several online instructions, such as this -
Eclipse exported Runnable JAR not showing images
But so far, no success.
I have a very simple program that reads a text file (test.txt) and prints out its contents to standard output. I am using Eclipse. Here is what I have done-
I put the text file into a folder called 'resources'
I right-clicked the resources folder, selected "Build path" and hit "Use as resource folder"
In my code, I tried two ways of addressing the file - (a) as "/test.txt" and (b) as "resources/test.txt. The latter method works when I run the program within Eclipse. However, neither method works when I export the project as a runnable jar file. The resource folder fails to be included in the jar file.
Any help will be much appreciated.
Addendum:
Here is the code.
public class FileIOTest {
public static void main(String[] args) {
String line;
try {
BufferedReader br = new BufferedReader(new FileReader(new File("/test.txt")));
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
}
catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}
}
}
You can not access a resource in a Jar file through a FileReader because it is not a file on the file system. Java does have a mechanism for accessing resources in your classpath (including in Jars): ClassLoader.getResourceAsStream(). You can use it with your default classloader:
BufferedReader br = new BufferedReader(new InputStreamReader(
ClassLoader.getSystemClassLoader()
.getResourceAsStream("test.txt")));
Note that getResourceAsStream returns null instead of throwing an exception, so you may want to get the stream first, check if for null, then either throw an exception or process it.
You will want to give the full path within the jar as your path.
Files work differently from resources. If you want a resource, then you should not be trying to use any of the File(Xxx) variants, which will look on the file system.
The link you provided, used Class.getResource which returns a URL, but there is also Class.getResourceAsStream which returns an InputStream, which you can wrap in an InputStreamReader. For example
InputStream is = FileIOTest.class.getResourceAsStream("/text.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
You can create jar without eclipse. For example, if I have a Demo class in package src (directory is the same), and the resource file (named testing.txt) is in resources directory. I add a Manifest.txt file # the root of the directory :
Manifest-Version: 1.0
Main-Class: src.Demo
The Demo class looks like :
package src;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo {
public static void main(String... args) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(Demo.class.getResourceAsStream("/resources/testing.txt"))))
{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The testing.txt file is like :
hello world
How are you?
Compile Demo.java to obtain Demo.class
javac src/Demo.java
Create jar
jar cfm myJar.jar Manifest.txt src/* resources/*
And run it
java -jar myJar.jar
In eclipse, just add the resources folder at the classpath (be sure it is in the jar), and read it as a classpath resource (the getResourceAsStream method)
Related
I'm trying to define a File in Java with a txt file called "helloworld". I've placed this file in a resources folder and when making the file I defined it like this:
File file = new File("/helloworld");
However I get this error when compiling
Exception in thread "main" java.io.FileNotFoundException: /helloworld
(No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileReader.<init>(FileReader.java:72)
at Tests.main(Tests.java:15)
This is the entire code I am trying to execute if that helps troubleshoot this issue
// Java Program to illustrate reading from FileReader
// using BufferedReader
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.net.URL;
public class Tests
{
public static void main(String[] args)throws Exception
{
File file = new File("/helloworld");
BufferedReader br = new BufferedReader(new FileReader(file));
String st;
while ((st = br.readLine()) != null)
System.out.println(st);
}
}
Thank you for the help!
public File(String pathname)
Creates a new File instance by converting the given pathname string
into an abstract pathname. If the given string is the empty string,
then the result is the empty abstract pathname.
You are trying to create a new File instance but the file called helloworld is not found or some other reasons. That's why you get the error,
Exception in thread "main" java.io.FileNotFoundException: /helloworld
The named file does not exist.
The named file is actually a directory.
The named file cannot be opened for reading for some reason.
You say that you try to define a file but your code seems to read. Try below one if you want to create a file,
import java.io.*;
import java.nio.charset.StandardCharsets;
class TestDir {
public static void main(String[] args) {
String fileName = "filename.txt";
try (Writer writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(fileName), StandardCharsets.UTF_8))) {
writer.write("write something in text file");
} catch (IOException e) {
e.printStackTrace();
}
}
}
It is easy to diagnose: The path you specified starts with a slash, so it means that the file is expected to be located at the root directory of the filesystem. You'd better strip off the leading slash, and:
Either start your program at the same directory the file is at.
Either specify an absolute/relative path in your code when instantiating the File object.
If the file is in a resources folder and is intended to be bundled with your program, you need to treat it like a resource, not a file.
This means you should not use the File class. You should read your data with the Class.getResource or Class.getResourceAsStream method:
BufferedReader br = new BufferedReader(
new InputStreamReader(
Tests.class.getResourceAsStream("/helloworld")));
This becomes especially important if you want to distribute a program as a .jar file. A .jar file is a compressed archive (actually a zip file with different extension) which contains both compiled class files and resources. Since they are all compressed into one .jar file, they are not individual files at all, so there is no way the File class can refer to them.
Although the File class is not useful for what you’re trying to do, you may want to research the concept of absolute file names and relative file names. By starting a file name with /, you are specifying an absolute file name, which means you are telling the program to look for the file in a specific place—a place where the file almost certain will not reside.
Try bellow to know where is the folder or file's path, which your program is looking for
System.out.println(file.getAbsolutePath());
With
File file = new File("/helloworld");
I think your program is looking for c:\helloworld, and there is no file or folder's name is helloword in your C drive
If you put the helloword.txt into C drive, and
File file = new File("C:\\helloworld.txt");
FileNotFoundException will disappear.
I am learning basic I/O for java, and the following example is from Oracle's tutorial. The program flows a FileNotFound exception. I place the file under the working directory, and I also tried to use absolute file path, and the result is still the same. I use Eclipse to write the code. What could be causing this exception? Thanks
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyBytes {
public static void main(String[] args) throws IOException {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
}
}
There are a lot of things that can cause that exception. Here are a few things to try:
-Verify that Xanadu.txt is a file using the isFile() method. If it returns false then you know where your problem is.
-Try placing the file in the project directory.
-Given that you already tried using the absolute file path I would also make sure that your program has permission to look at and write to the file. To check if eclipse has permission go to the properties of your file
Place the file xanadu.txt in the project directory and FileNotFoundException will go away.
FileInputStream will expect an existing input file.
The code probably isn't being executed from the path you expected.
You should use the home folder for this. C:\Users\<User Name> on windows and /home/<User Name> on linux. You can create a folder there to put your files.
To get the home directory, you can use this.
System.getProperty("user.dir")
Other solution would be to pack the files inside the JAR.
If you want to debug your problem, you can get the current directory like this.
<Your Class>.class.getProtectionDomain().getCodeSource().getLocation()
I am writing a java application, in which I am automatically importing external csv files in background to do the computation. But the problem is that I am using "absolute" file path in my java program, the generated jar file will not work in another computer. Is there anyway in java to use a kind of "working directory path" so that I can still run the jar file in another computer as long as I put the csv files I'd like to import in the same folder with the jar file?
Thanks!
You can read a file using its name like
try (BufferedReader br = new BufferedReader(new FileReader("text.txt"))) {
String line;
while ((line=br.readLine())!=null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
Here text.txt should be in the same working directory where the jar was executed.
You can also read the directory name from the command line, using the command line arguments like
public static void main(String[] args) {
//check if there were any command line arguments
if (args.length > 0) {
// args[0] is the first command line argument unlike C where args[0] would give u the executable's name
} else {
System.err.println("Usage: java -jar <jar_name> [directory_names..]");
}
}
You can also have a configuration file such as a properties file to read the directory names.
new File(".") give you the relative path
you can write relative path like that :
File file = new File(".\\CSVs\\myfile.csv");
System.getProperty("user.dir") will return you the working directory.
System.getProperty("user.dir")+"\\myfile.txt"
More informations here :system properties, oracle docs
I have the following code to read a text file.
public static void main(String[] args)
{
try
{
Scanner in = new Scanner(new FileReader("input.txt"));
while(in.hasNext())
{
System.out.println(in.next());
}
}
catch (FileNotFoundException ex)
{
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
I have my project structure set up as follows:
build/ directory contains class
dist/ directory contains the jar file
src/ directory contains source
input.txt the text file to read
If I put my textfile input.txt into a directory called test which is of the same directory as build, dist, and src, what should go into the parameter of filereader so that I can still find this file?
When running inside the Netbeans IDE the working directory is the root of the project, so to answer your question, "test/input.txt".
Note however that while this is perfectly fine for testing code, working with relative paths like this in final (production) code can be trickier. In those cases wrapping the file as a resource in the jar and opening it as a resourcestream may be a better solution, or of course working with absolute paths.
If you know the name of your subdirectory, just use
Scannner in = new Scanner(new FileReader("test/input.txt"));
I am developing a NetBeans module where I have a Java package called testand another package called test.templates. I want to read a text file which is in the test.templates package from a Java file in the test package. I tried in several ways, but it gives a FileNotFoundException exception:
BufferedReader br = new BufferedReader(new FileReader("templates/test.txt"));
BufferedReader br = new BufferedReader(new FileReader("/test/templates/test.txt"));
BufferedReader br = new BufferedReader(new FileReader("src/test/templates/test.txt"));
But none of these worked.. I want to use the relative path, not the absolute path. What should I do?
You will want to use getResource or getResourceAsStream.
Example on java2s.com:
http://www.java2s.com/Code/Java/Development-Class/Loadresourcefilerelativetotheclasslocation.htm
You should note somethings about relative path (Netbeans):
+ File: Default is project folder, means outside of src folder.
If you save to test.txt, it will generate: project/test.txt.
If you save to data/test.txt, ... project/data/test.txt
So if you want to load file, you just do it conversely. Like this, you should put your files in project/data/filename.txt. Then when code, you get path: data/filename.txt.
+ ImageIcon: I will share later if can.
+ Image(SplashScreen): I will share later.
getResource() returns a URL, so to extract the filename, you can try calling getFile().
The filepath you pass to getResource will be based on your netbeans package. Use a leading slash to denote the root of the classpath.
Example:
getResource(/db_files/table.csv).getFile()
try
{
BufferedReader br = new BufferedReader(new FileReader(getClass().getResource("/test/templates/test.txt").toString().substring(6)));
}
catch(Exception ee)
{
JOptionPane.showMessageDialog(this, ee);
}