The following code works fine on my Eclipse IDE.
private void getLayersAndDisplay() throws Exception {
URL imageURL = ImageLab.class.getResource("earthlights.jpg");
File imageFile = new File(imageURL.toURI());
URL shapeFileURL = ImageLab.class.getResource("countries.shp");
File shapeFile = new File(shapeFileURL.toURI());
URL shapeFileURL2 = ImageLab.class.getResource("Brasil.shp");
File shapeFile2 = new File(shapeFileURL2.toURI());
displayLayers(imageFile, shapeFile,shapeFile2);
}
However, when compiling to a jar, it gives me a null pointer exception. I thought that since I am getting it as a class.getResource, it would work. Can't I use the File class in a jar? Not even in a cast?
Thank you
An entry of a zip file (that's what a jar file is) is not a file existing in your file system. So you can't use a File, which represents a path on your filesystem, to refer to a zip entry. And you can't use file IO to read its content, since it's not a file.
I have no idea what you want to do, but if you want to read the content of the jar resource, just use ImageLab.class.getResourceAsStream() to get an InputStream back, reading from the entry.
Related
I have deployed a spring-boot application JAR file. Now, I want to upload the image from android and store it in the myfolder of resource directory. But unable to get the path of resource directory.
Error is:
java.io.FileNotFoundException: src/main/resources/static/myfolder/myimage.png
(No such file or directory)
This is the code for storing the file in the resource folder
private final String RESOURCE_PATH = "src/main/resources";
String filepath = "/myfolder/";
public String saveFile(byte[] bytes, String filepath, String filename) throws MalformedURLException, IOException {
File file = new File(RESOURCE_PATH + filepath + filename);
OutputStream out = new FileOutputStream(file);
try {
out.write(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
return file.getName();
}
UPDATED:
This is what I have tried
private final String RESOURCE_PATH = "config/";
controller class:
String filepath = "myfolder/";
String filename = "newfile.png"
public String saveFile(byte[] bytes, String filepath, String filename) throws MalformedURLException, IOException {
//reading old file
System.out.println(Files.readAllBytes(Paths.get("config","myfolder","oldfile.png"))); //gives noSuchFileException
//writing new file
File file = new File(RESOURCE_PATH + filepath + filename);
OutputStream out = new FileOutputStream(file); //FileNotFoundException
try {
out.write(bytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
return file.getName();
}
Project structure:
+springdemo-0.0.1-application.zip
+config
+myfolder
-oldfile.png
-application.properties
+lib
+springdemo-0.0.1.jar
+start.sh
-springdemo-0.0.1.jar //running this jar file
Usually when you deploy an application (or start it using Java), you start a JAR file. You don't have a resource folder. You can have one and access it, too, but it certainly won't be src/main/resources.
When you build your final artifact (your application), it creates a JAR (or EAR or WAR) file and your resources, which you had in your src/main/resources-folder, are copied over to the output directory and included in the final artifact. That folder simply does not exist when the application is run (assuming you are trying to run it standalone).
During the build process target/ is created and contains the classes, resources, test-resources and the likes (assuming you are building with Maven; it is a little different if you build using Gradle or Ant or by hand).
What you can do is create a folder e.g. docs next to your final artifact, give it the appropriate permissions (chmod/chown) and have your application output files into that folder. This folder is then expected to exist on the target machine running your artifact, too, so if it doesn't, it would mean the folder does not exist or the application lacks the proper permissions to read from / write to that folder.
If you need more details, don't hesitate to ask.
Update:
To access a resource, which is bundled and hence inside your artifact (e.g. final.jar), you should be able to retrieve it by using e.g. the following:
testText = new String(ControllerClass.class.getResourceAsStream("/test.txt").readAllBytes());
This is assuming your test.txt file is right under src/main/resources and was bundled to be directly in the root of your JAR-file (or target folder where your application is run from). ControllerClass is the controller, which is accessing the file. readAllBytes just does exactly this: read all the bytes from a text file. For accessing images inside your artifact, you might want to use ImageIO.
IF you however want to access an external file, which is not bundled and hence not inside your artifact, you may use File image = new File(...) where ... would be something like "docs/image.png". This would require you to create a folder called docs next to your JAR-artifact and put a file image.png inside of it.
You of course also may work with streams and there are various helpful libraries for working with input- and output streams.
The following was meant for AWT, but it works in case you really want to access the bytes of your image: ImageIO. In a controller you usually wouldn't want to do that, but rather have your users access (and thus download) it from a given available folder.
I hope this helps :).
I am getting an NPE at the point of getting path of a File (an sh file in assets folder).
I have tried to read about NPE i detail from the following thread, but this actually could not solve my problem.
What is a NullPointerException, and how do I fix it?
Following is my code snippet:
File absPathofBash;
url = ClassLoader.class.getResource("assets/forbackingup.sh");
absPathofBash = new File(url.getPath());
Later I'm using it in a ProcessBuilder, as
ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3)
I've also tried getting the absolute path directly, like
absPathofBash = new File("assets/forbackingup.sh").getAbsolutePath();
Using the latter way, I am able to process it, but if I create a jar then the file cannot be found. (although the Jar contains the file within the respective folder assets)
I would be thankful if anyone can help me on that.
Once you have packaged your code as a jar, you can not load files that are inside the jar using file path, instead they are class resources and you have to use this to load:
this.getClass().getClassLoader().getResource("assets/forbackingup.sh");
This way you load assets/forbackingup.sh as an absolute path inside your jar. you also can use this.getClass().getResource() but this way the path must be relative to this class path inside jar.
getResource method gives you an URL, if you want to get directly an InputStream you can use getResourceAsStream
Hope it helps!
Since the file itself is in the jar file, you could try using:
InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileNameFromJar);
In case of jar file , classloader will return URL different than that of when the target file is not embedded inside jar. Refer to answer on link which should help u :
How to use ClassLoader.getResources() in jar file
I got it done by creating a temp file. Though it's not difficult, yet I'm posting the code patch here:
InputStream stream = MyClass.class.getClassLoader().
getResourceAsStream("assets/forbackingup.sh");
File temp = File.createTempFile("forbackingup", ".sh");
OutputStream outputStream =
new FileOutputStream(temp);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
outputStream.close();
}
Now, we have this temp file here which we can pipe to the ProcessBuilder like,
String _filePath=temp.getPath();
ProcessBuilder pb = new ProcessBuilder(url.getPath(), param2, param3)
Thank you everyone for your considerations.
You can use Path class like :
Path path = Paths.get("data/test-write.txt");
if(!Files.exists(path)){
// can handle null pointer exception
}
I have a text file, that I am trying to convert to a String array (where each line is an element of the array).
I have found a code here that seems to do this perfectly, the only problem is, even when I use the relative path of the file, I get a FileNotFoundException.
The relative file path:
String path = "android.resource://"+getPackageName()+"/app/src/main/res/raw/"
+ getResources().getResourceEntryName(R.raw.txtAnswers);
When I try to use this path in a reader
BufferedReader reader = null;
try{
reader = new BufferedReader(new FileReader(path));
......
The path is underlined in red and says FileNotFoundException.
Perhaps it is expecting another type of path (not relative?) or did I get the path wrong?
The relative file path
That is not a file path.
Perhaps it is expecting another type of path
res/raw/... is a file on your hard drive. It is not a file on the device.
To access raw resources, use getResources() (called on any Context, like an Activity or Service) to get a Resources object. Then, call openRawResource(), passing in your resource ID, to get an InputStream on that resource's contents.
According to me the best way would be to past that txt file in assets folder of your source code.
To use that File just use the following snippet:
InputStream inputStream = getAssets().open("YOUR_TEXT_FILE");
It returns InputStream which further can be used to read the File & convert the data into a Array
I'm trying to figure out how to add a lot of images into my Java program without having to add every file name in the code.
So I want to take all the .png images in the correct folder and make them into an IconImage and then place them in an ArrayList.
What I've got right now is this.
private void fillList()
{
File[] files = new File("C:/Users/marre/Google Drive/Java/lek/imageplay/src/img").listFiles();
for (File f : files)
{
if (f.isFile())
{
ImageIcon tempIcon = new ImageIcon(getClass().getResource("/img/"+f.getName()));
List.add(tempIcon);
}
}
}
This works the way I want it to regarding getting the names of all images. But the file only reads from absolute file path.
What can I use instead to get the same result, but that works within .jar file (so it reads from src/img/ and not the whole c:/ bla bla..)?
I'm not sure if this will be helpful but I had a similar issue in attempting to obtain files within a jar file. In the case this can be useful to you, my approach was to obtain the URL for the files inside the jar using the ClassLoader:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL url = classLoader.getResource("src/img/");
Check inside your jar to make sure of the directory structure for the images so you can specify the correct relative path.
Keep in mind, a jar is a packaged form, so this will most likely return a zipped file (and not a simple File object). You might have to dabble in ZipFile.
ZipFile folderInsideJar = new ZipFile(new File(url.getPath());
Enumeration<? extends ZipEntry> entries = folderInsideJar.entries();
while (entries.hasMoreElements()) {
// ideally this would be your image file, zipped
ZipEntry childFile = entries.nextElement();
// ... etc ...
}
For environments such as JBoss, etc, you might also get virtual files (vfsfile/vfszip). Point being, you can determine what you are dealing with by looking at the result URL.getProtocol().
It would also appear ImageIcon has a constructor that takes a URL. You might try giving this a shot to see if it handles the "resource inside jar" case before manually attempting to retrieve the zip file.
I try to write to a Csv file via:
mFileWriter = new FileWriter(
"/sdcard/program/file");
mCsvWriter = new CSVWriter(mFileWriter);
At the moment it throws an exception that the file doesn't exist.
It's true that the file doesn't exist. What's the easiest way to create the file?
Does the FILE not exist, or the DIRECTORY it's supposed to go into?
If you want to create a directory structure, you can always do
File file = new File("/full/path/to/file");
file.mkdirs();
This will create any path leading up to this file that doesn't exist yet.
I suppose the missing quotes around your file name are a typo?