public class Main {
public static void main(String[] args) throws IOException {
System.out.println("----------Start------------------");
URL resource = Main.class.getClassLoader().getResource("test.txt");
System.out.println("resource: "+ resource.getPath());
File file = new File(resource.getPath());
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
System.out.println("----------End------------------");
}
}
If I run this code from IDEA - all work
----------Start------------------
resource: /D:/javaHz/target/classes/test.txt
1
2
3
4
5
----------End------------------
Process finished with exit code 0
if I reun from java -jar - I get error
D:\hz>java -jar hzTest-jar-with-dependencies.jar
----------Start------------------
resource: file:/D:/hz/hzTest-jar-with-dependencies.jar!/test.txt
Exception in thread "main" java.io.FileNotFoundException: D:\hz\file:\D:\hz\hzTe st-jar-with-dependencies.jar!\test.txt (Syntax error in file name, folder name, or volume label)
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.FileInputStream.<init>(FileInputStream.java:93)
at java.io.FileReader.<init>(FileReader.java:58)
at test.Main.main(Main.java:15)
I do not want use getResourceAsStream
new File(resource.getPath()) won't work because file:/D:/hz/hzTest-jar-with-dependencies.jar!/test.txt isn't really a filesystem path.
Since the file is part of jar file (a zip archive in fact), there is no valid filesystem path that would point to it.
The standard way is to use getClassLoader().getResourceAsStream("test.txt");. You'll either have to modify your application so that it can read from classpath resources or URLs, or use getResourceAsStream() to copy the resource to a temporary file on filesystem and then point to it.
The correct way to translate a URL to a absolute path that you can use outside Java is this:
import java.net.URL;
import java.nio.file.Paths;
URL resource = Main.class.getClassLoader().getResource("test.txt");
String absolutePath = Paths.get(resource.toURI()).toAbsolutePath());
This only works right if the resource comes from a file:// url - if your application was built as a jar file, it won't work, as other applications cannot look inside a jar file directly.
It look a bit convoluted, and it is. To break this down a bit:
URL resource = ...;
URI uri = resource.toURI();
Path path = Paths.get(uri);
String absolutePath = path.toAbsolutePath();
File file = new File(resource.getPath());
Bzzt. Resources are not files. You have a URL. Use its input stream directly.
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.
This question already has answers here:
File inside jar is not visible for spring
(13 answers)
Closed 4 years ago.
Error :
java.io.FileNotFoundException: class path resource [xml/ruleSet.xml] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app/target/******-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/xml/ruleSet.xml
Code :
File ruleSet = new ClassPathResource("xml/ruleSet.xml").getFile();
pmdConfiguration.setReportFormat("text");
pmdConfiguration.setRuleSets(ruleSet.getAbsolutePath());
I need to insert the full file into the setRuleSets method, how will FileInputStream help me here?
FileInputStream ruleSet = new FileInputStream(ClassLoader.getSystemResource
("xml/ruleSet.xml").getPath());
Should I recreate a temp file by reading the fileinput stream and pass that file path to setRuleSets method?
The fundamental problem is that there is no path in the file system namespace for a resource in a JAR file. That is why ClassPathResource::getFile is throwing an exception, and it is also why URL::getPath.
There is an alternative. Use an InputStream, not a FileInputStream, and use the classloader API method for opening a resource as a stream.
Change:
FileInputStream ruleSet = new FileInputStream(ClassLoader.getSystemResource
("xml/ruleSet.xml").getPath());
to
InputStream ruleSet = ClassLoader.getSystemResourceAsStream("xml/ruleSet.xml");
In this case, this won't work because PMDConfiguration::setRuleSets doesn't take a stream argument.
However, the javadoc states:
public void setRuleSets(String ruleSets)
Set the command1 separated list of RuleSet URIs.
Since the getResource methods return a URL, you should be able to do this:
pmdConfiguration.setRuleSets(
ClassLoader.getSystemResource("xml/ruleSet.xml").toString();
UPDATE
If getSystemResource or getSystemResourceAsStream fails, then either the resource does not exist (in the JARs, etc on the runtime classpath), the path is incorrect, or you should be using getResource or getResourceAsStream.
1 - The word "command" is a typo. It should be "comma".
Ok So I figured out what to do here,
We already have input stream, thus I converted input stream to a temp file, and used that file.getPath.
ClassLoader classLoader = this.getClass().getClassLoader();
InputStream resourceAsStream = classLoader.getResourceAsStream("xml/ruleSet.xml");
String ruleSetFilePath = "";
if(resourceAsStream != null){
File file = stream2file(resourceAsStream);
ruleSetFilePath = file.getPath();
}
pmdConfiguration.setRuleSets(ruleSetFilePath);
public static File stream2file (InputStream in) throws IOException {
final File tempFile = File.createTempFile("ruleSet", ".xml");
tempFile.deleteOnExit();
try (FileOutputStream out = new FileOutputStream(tempFile)) {
IOUtils.copy(in, out);
}
return tempFile;
}
I have an excel file which I have kept in a subfolder of my main package.
I want to read that file. When I read it using InputStream, it file is easily detected but when I read using FileInputStram or File file = new File(filepath) I get the error that the file is not found.
Can anyone help me in reading the file using FileInputStram or File file = new File(filepath)?
The code what I wrote to read the file is
File file = new File("upgradeworkbench/Resources/workbookOut.xlsm");
and
FileInputStream inp = new FileInputStream("upgradeworkbench/Resources/workbookOut.xlsm");
I tried with / in the beginning of the path but still it didn't work.
When working with File class you need to provide either absolute or relative path. Absolute path is the full file path e.g. C:\workbookOut.xlsm
In relative paths, there is a concept of a working directory and it's represented by a . (dot) and everything else is relative to it.
Try either giving the full path or the relative path.
File file = new File("./upgradeworkbench/Resources/workbookOut.xlsm");
If your file in classpath then try below code
package mypack;
import java.io.*;
public class TestPath
{
public static void main(String[] args) throws Exception
{
InputStream stream = Test.class.getResourceAsStream("/workbookOut.xlsm");
System.out.println(stream != null);
stream = Test.class.getClassLoader()
.getResourceAsStream("workbookOut.xlsm");
System.out.println(stream != null);
}
}
If your file in same package then use the below line it will work
URL url = getClass().getResource("workbookOut.xlsm");
File file =new File(url.getPath());
So I'm trying to read in from a config file in my Eclipse project, but it can't locate the file. Here's my code.
public void readConfigFile () {
//URL url = Test.class.getClassLoader().getResource("myfile.txt");
//System.out.println(url.getPath());
URL url = getClass().getResource("/config");
System.out.println(url);
try {
BufferedReader read = new BufferedReader(new FileReader(url.toString()));
//read in values for constants from config file
System.out.println(BASE_URL);
BASE_URL = read.readLine().split("\t")[1];
System.out.println(BASE_URL);
read.close();
}
catch (Exception e)
{
System.out.println("Read from config file failed. Terminating program");
System.out.println(e);
System.exit(1);
}
}
When I run, it prints the url variable as:
/Users/myname/Development/workspace/New_API/bin/config
But it fails to find the file when running the BufferedReader command. I get:
Read from config file failed. Terminating program
java.io.FileNotFoundException:
file:/Users/myname/Development/workspace/New_API/bin/config.txt (No such file or directory)
When I go to the bin directory of my code however, the config file is there. In the root bin directory, following the exact path given by the URL. What is messing Eclipse up?
When getting a resource from the class loader, you're getting it from the classpath, not from the file system. If your application was packaged as a jar, you wouldn't have access to the resource through the File or FileInputStream APIs since the resource is part of the archive. Instead, you can access the input stream of the resource like so:
URL url = getClass().getResource("/config");
BufferedReader read = new BufferedReader(new InputStreamReader(url.openStream()));
// more...
I have a project with 2 packages:
tkorg.idrs.core.searchengines
tkorg.idrs.core.searchengines
In package (2) I have a text file ListStopWords.txt, in package (1) I have a class FileLoadder. Here is code in FileLoader:
File file = new File("properties\\files\\ListStopWords.txt");
But I have this error:
The system cannot find the path specified
Can you give a solution to fix it?
If it's already in the classpath, then just obtain it from the classpath instead of from the disk file system. Don't fiddle with relative paths in java.io.File. They are dependent on the current working directory over which you have totally no control from inside the Java code.
Assuming that ListStopWords.txt is in the same package as your FileLoader class, then do:
URL url = getClass().getResource("ListStopWords.txt");
File file = new File(url.getPath());
Or if all you're ultimately after is actually an InputStream of it:
InputStream input = getClass().getResourceAsStream("ListStopWords.txt");
This is certainly preferred over creating a new File() because the url may not necessarily represent a disk file system path, but it could also represent virtual file system path (which may happen when the JAR is expanded into memory instead of into a temp folder on disk file system) or even a network path which are both not per definition digestable by File constructor.
If the file is -as the package name hints- is actually a fullworthy properties file (containing key=value lines) with just the "wrong" extension, then you could feed the InputStream immediately to the load() method.
Properties properties = new Properties();
properties.load(getClass().getResourceAsStream("ListStopWords.txt"));
Note: when you're trying to access it from inside static context, then use FileLoader.class (or whatever YourClass.class) instead of getClass() in above examples.
The relative path works in Java using the . specifier.
. means same folder as the currently running context.
.. means the parent folder of the currently running context.
So the question is how do you know the path where the Java is currently looking?
Do a small experiment
File directory = new File("./");
System.out.println(directory.getAbsolutePath());
Observe the output, you will come to know the current directory where Java is looking. From there, simply use the ./ specifier to locate your file.
For example if the output is
G:\JAVA8Ws\MyProject\content.
and your file is present in the folder "MyProject" simply use
File resourceFile = new File("../myFile.txt");
Hope this helps.
The following line can be used if we want to specify the relative path of the file.
File file = new File("./properties/files/ListStopWords.txt");
InputStream in = FileLoader.class.getResourceAsStream("<relative path from this class to the file to be read>");
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
try .\properties\files\ListStopWords.txt
I could have commented but I have less rep for that.
Samrat's answer did the job for me. It's better to see the current directory path through the following code.
File directory = new File("./");
System.out.println(directory.getAbsolutePath());
I simply used it to rectify an issue I was facing in my project. Be sure to use ./ to back to the parent directory of the current directory.
./test/conf/appProperties/keystore
While the answer provided by BalusC works for this case, it will break when the file path contains spaces because in a URL, these are being converted to %20 which is not a valid file name. If you construct the File object using a URI rather than a String, whitespaces will be handled correctly:
URL url = getClass().getResource("ListStopWords.txt");
File file = new File(url.toURI());
Assuming you want to read from resources directory in FileSystem class.
String file = "dummy.txt";
var path = Paths.get("src/com/company/fs/resources/", file);
System.out.println(path);
System.out.println(Files.readString(path));
Note: Leading . is not needed.
I wanted to parse 'command.json' inside src/main//js/Simulator.java. For that I copied json file in src folder and gave the absolute path like this :
Object obj = parser.parse(new FileReader("./src/command.json"));
For me actually the problem is the File object's class path is from <project folder path> or ./src, so use File file = new File("./src/xxx.txt"); solved my problem
For me it worked with -
String token = "";
File fileName = new File("filename.txt").getAbsoluteFile();
Scanner inFile = null;
try {
inFile = new Scanner(fileName);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while( inFile.hasNext() )
{
String temp = inFile.next( );
token = token + temp;
}
inFile.close();
System.out.println("file contents" +token);
If text file is not being read, try using a more closer absolute path (if you wish
you could use complete absolute path,) like this:
FileInputStream fin=new FileInputStream("\\Dash\\src\\RS\\Test.txt");
assume that the absolute path is:
C:\\Folder1\\Folder2\\Dash\\src\\RS\\Test.txt
String basePath = new File("myFile.txt").getAbsolutePath();
this basepath you can use as the correct path of your file
if you want to load property file from resources folder which is available inside src folder, use this
String resourceFile = "resources/db.properties";
InputStream resourceStream = ClassLoader.getSystemClassLoader().getResourceAsStream(resourceFile);
Properties p=new Properties();
p.load(resourceStream);
System.out.println(p.getProperty("db"));
db.properties files contains key and value db=sybase
If you are trying to call getClass() from Static method or static block, the you can do the following way.
You can call getClass() on the Properties object you are loading into.
public static Properties pathProperties = null;
static {
pathProperties = new Properties();
String pathPropertiesFile = "/file.xml";
// Now go for getClass() method
InputStream paths = pathProperties.getClass().getResourceAsStream(pathPropertiesFile);
}