We trying to get bytes from a file using below code.
getBytes("/home/1.ks");
Before that, we have make sure the file is exists.
public static void getBytes(final String resource) throws IOException {
File file = new File(resource);
if (file.exists()) {
System.out.println("exists");
} else {
System.out.println("not exists");
}
final InputStream input = APIController.class.getResourceAsStream(resource);
if (input == null) {
throw new IOException(resource);
} else {
System.out.println("Not null");
}
}
Here the output and exceptions
exists
java.io.IOException: /home/1.ks
at com.example.demo.controller.APIController.getBytes(APIController.java:164)
at com.example.demo.controller.APIController.transactionSale(APIController.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
Change your line to :
final InputStream input = new FileInputStream(resource);
While you're at it, change the name of the parameter resource to path or filePath, since that is what it really is.
The two concepts (file and resource) are related but not the same. A resource can be a file on disk, but it can also be a file inside a jar file or it could be a resource loaded from a remote URL (not often used, but possible).
Since in your case, you know that you want to access a file on disk, you need to use FileInputStream.
See also What's the difference between a Resource, URI, URL, Path and File in Java? for a deeper explanation of the differences between files, resources and related concepts.
Related
I am getting Sonar vulnerability on below piece of code. How can I solve this vulnerability?
code
public static final String getFilePath(String configFileName) throws FileNotFoundException {
File configFile = new File(FilenameUtils.getName(configFileName));
if (configFile.exists()) {
return configFile.getAbsolutePath();
}
URL url = ConfigHelper.class.getClassLoader().getResource(configFileName);
if (url != null) {
return url.getPath();
}
logger.error("Failed to find the file on classpath:" + configFileName);
return null;
}
Error
What exactly is this method meant to do? What it actually does is:
Takes an input argument which may contain a full path, e.g. "/path/to/file.ext"
Throws away the path (using FileNameUtils), getting just "file.ext"
Checks to see if the file exists in the current directory.
So if the user does cd /some/dangerous/directory and then runs your application, even if your method is passed "/a/safe/directory/file.ext", if the file file.ext exists in /some/dangerous/directory then your method will return "/some/dangerous/directory/file.ext". If the user copies a virus and names it "file.ext" in that dangerous directory, you might be in trouble.
This question already has an answer here:
Java File does not exists but File.getAbsoluteFile() exists
(1 answer)
Closed 5 years ago.
It works well "new FileInputStream(f.getAbsoluteFile())"
private byte[] loadFile(String path) throws IOException {
File f = new File("./build/classes/" + path);
try (InputStream is = new FileInputStream(f.getAbsoluteFile())) {
byte[] data = loadFile(is);
return data;
}
}
And "new FileInputStream(f)"
private byte[] loadFile(String path) throws IOException {
File f = new File("./build/classes/" + path);
try (InputStream is = new FileInputStream(f)) {
byte[] data = loadFile(is);
return data;
}
}
throw exception:
java.io.FileNotFoundException: ./build/classes/traces/onmethod/ErrorDuration.class (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)
I can't imagine why.
First make sure you run your two programs from the same working directory.
Also, in the first case, your path is resolved to an absolute path first.
For example: /opt/local/myprod/bin/build/classes/traces/onmethod/ErrorDuration.class
Whle FileInputStream uses the 'simple path' of your file (File.getPath())
Depending on your current work directory, your permissions and your symbolic links those two paths can mean two different things.
From the directory you run your program - does this path work ?
ls ./build/classes/traces/onmethod/ErrorDuration.class
Also see:
What's the difference between getPath(), getAbsolutePath(), and getCanonicalPath() in Java?
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I keep getting a java.lang.NullPointerException when trying to open a txt file in eclipse. Basically, this is a main menu, and when you click the "Rules" button, the rules text file should open. Currently, the txt file is located in a package called "Resources" (which is where all of the other img files I've used in making the game are). Here's the code:
private List<String> readFile(String filename)
{
List<String> records = new ArrayList<String>();
try
{
BufferedReader buff = new BufferedReader(new InputStreamReader(
Configuration.class.getResourceAsStream(filename)));
String line;
while ((line = buff.readLine()) != null)
{
records.add(line);
}
buff.close();
return records;
}
catch (Exception e)
{
System.err.format("Exception occurred trying to read '%s'.", filename);
e.printStackTrace();
return null;
}
}
//action performed
public void actionPerformed(ActionEvent ae) {
JButton b = (JButton)ae.getSource();
if( b.equals(newGameButton) )
{
flag = true;
controller.startGame();
buttonPressed = "newGameBtn";
}
if(b.equals(quitButton))
{
System.exit(0);
}
if(b.equals(ruleButton)){
readFile("../resource/riskRules.txt");
}
}
Appreciate the help!
If "Resources" it's marked as resource in Eclipse. The txt file should be copied to your class path when you build.
As per what I can guess from your code you should be doing something like
Configuration.class.getResourceAsStream("riskRules.txt")
Since your file will be at the root level of your class path.
If for example the file is withing a dir called "text" in your resources you would use something like
Configuration.class.getResourceAsStream("text/riskRules.txt")
There needs to be some level of rudimentary error checking on the result returned from getResourceAsStream before you attempt to use it. Is there a reason you're using getResourceAsStream instead of getResource? If the file exists on disk (I see from your OP that it's because it's in a package, and may not physically exist on the disk), then you can just use that to return the path to it, and create a file object from it.
String path = "/path/to/resource"; // note the leading '/' means "search from root of classpath"
URL fileUrl = getClass().getResource(path);
if (fileUrl != null ) {
File f = new File(fileUrl.toURI());
BufferedReader = new BufferedReader(new FileReader(f));
// do stuff here...
}
else {
// file not found...
}
If you need to pull the file out of the JAR archive, then you can do this:
String path = "/path/to/resource"; // note the leading '/' means "search from root of classpath"
InputStream is = getClass().getResourceAsStream(path);
if (is != null ) {
BufferedReader = new BufferedReader(new InputStreamReader(is));
// do stuff here...
}
else {
// file not found...
}
In the event your resource is not found, you will avoid the NPE and you can properly account for the fact that it's missing.
Note that if you do have your resources in a package (jar), then you cannot use a path to locate it that uses "..", since there is no "relative path" in a jar archive, it's not actually a file on the filesystem.
Your "resources" are located by the relative path you specify in the getResource... method. A leading "/" means to look at the root of your classpath for locating the resource. No leading "/" means to look relative to the location of the class file that you're using to locate the resource.
If your file is in a location called "com.program.resources", and you're trying to locate it from a class called "com.program.someotherpackage.MyClass", then you'd use:
getClass().getResourceAsStream("/com/program/resources/<file.txt>");
to find it.
Here's my example illustrated:
<classpath root>
com
program
resources
file.txt
img.png
someotherpackage
MyClass.class
Generally, it's common practice to leave resources outside your package structure, to avoid confusion when locating them later. Most IDE's have a way to mark your directories as resources, so when the program is compiled, they will be copied to the proper location in the classpath root, and can be found by any class asking for them.
I want to read a file in my java class. My question is similar to this one, but there are two differences. first, I use a different project layout:
/src/com/company/project
/resources
In the resources folder I have a file called "test.txt":
/resources/test.txt
In the project folder I have a class test.java
/src/com/company/project/test.java
I want mu java class to be able to read the contents of test.txt in a STATIC METHOD. I've tried the following:
private static String parseFile()
{
try
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
String fileURL = classLoader.getResource("test.txt").getFile();
File file = new File(fileURL);
...
}
}
and the following paths:
File file1 = new File("test.txt");
File file2 = new File("/test.txt");
File file3 = new File("/resources/test.txt");
But they all throw a FileNotFoundException when I want to read the file. How can I correctly declare the path to my file in the snippet above with respect to my project setup and the fact that the method needs to be static?
You should use the class loader of the class which is in the same JAR as the resource instead of the TCCL. And then you need to specify the name of the resource with a full path. And it is typically not good to access those as files. Just open it directly for read (or copy it to a temp file if you need to):
InputStream is =
Project.class.getClassLoader().getResourceAsStream("/resource/test.txt");
BTW: if you simply want to open a file, you need to use a relative file name. This is searched relative to the start dir, which is normally the project main dir (in eclipse):
File resource = new File("resource/test.txt");
(but this wont work if you package it up as a JAR).
After endless trials, I gave up on ClassLoader and getResource methods of any kind.
Absolutely nothing worked, especially if the opening attempt was made from another project. I always ended up getting the bin folder instead of the src folder.
So I devised the following work around:
public class IOAccessory {
public static String getProjectDir() {
try {
Class<?> callingClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
URL url = callingClass.getProtectionDomain().getCodeSource().getLocation();
URI parentDir = url.toURI().resolve("..");
return parentDir.getPath();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return "";
}
}
The getProjectDir method returns the physical path of the project from which it was called, e.g. C:/workspace/MyProject/.
After that, all you need to do is concatenate the relative path in MyProject of your resource file to open the stream:
public void openResource() throws IOException {
InputStream stream = null;
String projectDir = IOAccessory.getProjectDir();
String filePath = "resources/test.txt";
try {
stream = new FileInputStream(projectDir + filePath);
open(stream);
} catch(Exception e) {
e.printStackTrace();
} finally {
if (stream != null)
stream.close();
}
}
This technique works whether the openResource method is static or non-static, and whether it is called from within the project or from another project on the build path.
It really depends on how your IDE generates output from your project. Typically, classloaders load resources relative to the invoking classes, but if treated right, 'resources' will just end up in the 'root' of your output folder hierarchy, and you can access them accordingly.
For example, if I recreate your code in IntelliJ IDEA, in a class called com/acme/TestClass.class, the following output structure is generated within the IDE when building. This assumes I have "test.txt" sitting in a folder I called "resources", and that folder is specified as being a "resources root":
/com
/acme
TestClass.class
test.txt
The text file ends up in the output folder's root, so accessing it is simple. The following code works for me when I attempt to load the file in a static method within TestClass:
ClassLoader cl = TestClass.class.getClassLoader();
InputStream is = cl.getResourceAsStream("test.txt");
The only thing not covered in the other answers is that your URL conversion to file might not work correctly. If the directories above your project contain a characters that must be decoded then your call to 'getResource("test.txt").getFile()' is not giving you a valid java.io.File path.
I load shader for openGL ES from static function.
Remember you must use lower case for your file and directory name, or else the operation will be failed
public class MyGLRenderer implements GLSurfaceView.Renderer {
...
public static int loadShader() {
// Read file as input stream
InputStream inputStream = MyGLRenderer.class.getResourceAsStream("/res/raw/vertex_shader.txt");
// Convert input stream to string
Scanner s = new Scanner(inputStream).useDelimiter("\\A");
String shaderCode = s.hasNext() ? s.next() : "";
}
...
}
Another method to convert input stream to string.
byte[] bytes;
String shaderCode = "";
try {
bytes = new byte[inputStream.available()];
inputStream.read(bytes);
shaderCode = new String(bytes);
}
catch (IOException e) {
e.printStackTrace();
}
If I do this:
File f = new File("c:\\text.txt");
if (f.exists()) {
System.out.println("File exists");
} else {
System.out.println("File not found!");
}
Then the file gets created and always returns "File exists". Is it possible to check if a file exists without creating it?
EDIT:
I forgot to mention that it's in a for loop. So here's the real thing:
for (int i = 0; i < 10; i++) {
File file = new File("c:\\text" + i + ".txt");
System.out.println("New file created: " + file.getPath());
}
When you instantiate a File, you're not creating anything on disk but just building an object on which you can call some methods, like exists().
That's fine and cheap, don't try to avoid this instantiation.
The File instance has only two fields:
private String path;
private transient int prefixLength;
And here is the constructor :
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
As you can see, the File instance is just an encapsulation of the path. Creating it in order to call exists() is the correct way to proceed. Don't try to optimize it away.
Starting from Java 7 you can use java.nio.file.Files.exists:
Path p = Paths.get("C:\\Users\\first.last");
boolean exists = Files.exists(p);
boolean notExists = Files.notExists(p);
if (exists) {
System.out.println("File exists!");
} else if (notExists) {
System.out.println("File doesn't exist!");
} else {
System.out.println("File's status is unknown!");
}
In the Oracle tutorial you can find some details about this:
The methods in the Path class are syntactic, meaning that they operate on the Path instance. But eventually you must access the file system to verify that a particular Path exists, or does not exist. You can do so with the exists(Path, LinkOption...) and the notExists(Path, LinkOption...) methods. Note that !Files.exists(path) is not equivalent to Files.notExists(path). When you are testing a file's existence, three results are possible:
The file is verified to exist.
The file is verified to not exist.
The file's status is unknown. This result can occur when the program does not have access to the file.
If both exists and notExists return false, the existence of the file cannot be verified.
Creating a File instance does not create a file on the file system, so the posted code will do what you require.
The Files.exists method has noticeably poor performance in JDK 8, and can slow an application significantly when used to check files that don't actually exist.
This can be applied too for Files.noExists, Files.isDirectory and Files.isRegularFile
According this you can use the following :
Paths.get("file_path").toFile().exists()