I noticed that when I try to load a resource (an image, data, sound file, ect.) it is not possible to put it in the same file as the source code and just type "soundfiles/sound.wav". What is the best way to get this url?
Specifically here:
// load wave data from buffer
WaveData wavefile = WaveData.create("spaceinvaders/" + path);
I have done this before in many different ways, just wondering what the best way is.
If you ship your application in jar it's common way to package resources also in jar and access them using classloader:
//jar structure
your.jar
|--com
| `--... //classes here
`--resources
`--spaceinvaders
`--sound.wav
And code to access:
InputStream resource = getClass().getClassLoader().getResourceAsStream("resources/spaceinvaders/sound.wav");
Related
If I want to access a directory, I would to the following:
File f = new File(getFilesDir()+"/name");
And then, if f is a directory, I can iterate through the files and do a lot of things.
Can I do the same with the drawable/raw folder? I know how to get the id of a file using the name or the name using the id, but I am not sure how can I use drawable as a directory. I also need to use FileInputStream on some files, so I need a file type, not an id or a name.
I found some 'some what' related questions, like this one: Retrieving all Drawable resources from Resources object
But my problem is a bit different. I know how to get a resource in this way. By getting the id you can do lots of things, but as far as I know, you can not use FileInputStream. That's what I need: the possibility to use FileInputStream on a resource that is inside a project folder(drawable or raw).
Can I do the same with the drawable/raw folder?
Not really.
the possibility to use FileInputStream on a resource that is inside a project folder(drawable or raw)
Resources are not files. You cannot get a FileInputStream on them.
For raw resources, you can call openRawResource() on a Resources object to get an InputStream, though.
I am making a program that needs to save objects for retrieval at a future date. The program will be given out away as a jar file to different people.
I can already store and retrieve instances of classes when giving the Object input/output stream a absolute path (String) as a parameter.
I can also save images and text files in the resources folder and get it as a resource with getClass().getResource(String path).
Here is the problem:
I have tried every way possible to save/get Objects to/from the resources folder. It gets really weird dealing with URLS and Files and not ordinary Strings. Can someone please help me? I need to be able to save and retrieve objects relative to the classpath so that i can access the objects when the program is a jar file saved in different paths on the computer.
1: resource folder (in jar), is read-only.
You can create datas, store in the jar when you package, but after, it is finished: only to read.
2: so you want user can read and write (and it is not embedded in your app).
if it is personal datas, you can use (for PC):
String appdata= System.getenv("APPDATA");
System.out.println(appdata);
String dataFolder = System.getProperty("user.home") + "\\Local Settings\\ApplicationData";
System.out.println(dataFolder);
String dataFolder2 = System.getenv("LOCALAPPDATA");
System.out.println(dataFolder2);
on my PC, it gives:
C:\Users\develop2\AppData\Roaming
C:\Users\develop2\Local Settings\ApplicationData
C:\Users\develop2\AppData\Local
see this: What is the cross-platform way of obtaining the path to the local application data directory?
it is is for everybody, same principles, but you can encounter security issues
like this:
String programdata = System.getenv("PROGRAMDATA");
System.out.println(programdata);
String allusersprofile = System.getenv("ALLUSERSPROFILE");
System.out.println(allusersprofile); // same thing !
String publicdir = System.getenv("PUBLIC");
System.out.println(publicdir);
I've built a Java application that loads an image at runtime. The location of the image is fixed relative to the project.
I would like to be able to run the program from both within Eclipse and the command line and for it to load the image correctly. However, I can only do one or the other but not both. This seems like such a trivial thing to want to do but I can't find out how to do it.
The project is set up so that it creates a bin directory for the output and puts the image in a resources sub-folder. This is fine when running from the command line as I can write my code to look in that sub folder for the file.
But when I run the program from within eclipse the current working directory is different.
What am I missing?
TIA
Update - adding some code
This is what I had originally:
BufferedImage awtImage = ImageIO.read(new File(System.getProperty("user.dir") + "/resources/image-name.png"));
Following the advice in the comments I am trying to use getResourceAsStream but I don't know what to pass to the File constructor.
InputStream temp = MyClass.class.getResourceAsStream("resources/image-name.png");
BufferedImage awtImage = ImageIO.read(new File(???));
The resource is being found because temp is not null.
I think there's 2 solutions.
1) you specify an absolute path
2) your image is in the classpath so you could load it via :
YouClass.class.getResourceAsStream("YourImg.png");
The working directory, if that's really what you mean, is not a great place to load an image from. It appears that you have an image that you would distribute with your finished program so that the program could use it. In that case, I suggest that you use Class.getResourceAsStream(), and put the image in the directory with (or near) that class.
EDIT:
Here is code I used in one of my programs for a similar purpose:
ImageIcon expandedIcon = null;
// ...
expandedIcon = new ImageIcon(TreeIcon.class.getResource("images/Expanded.png"));
The ImageIcon class is part of Swing; I don't know if you're using that, but this should serve to show you the idea. The getResource() method takes a URL; again, you might need something a little different. But this shows the pathname relative to the path of the class on which the method is called, so if TreeIcon is in x/y/z/icons, the PNG file needs to be in x/y/z/icons/images, wherever that is on that computer.
TreeIcon is a class of mine, and its internals will not help you, so I'm not posting them. All it's doing here is providing a location for the PNG file I'm loading into an ImageIcon instance.
In addition to working on a disk with a directory structure, this also works in a jar file (which is a common way to distribute a java program or library). The jar file is just a zip file, and each file in the jar/zip file has its directory associated with it, so the image can be in the jar in the correct directory just as the java classes are in their directories.
getResourceAsStream() returns a stream; if you want to use that byte stream to load as an image, find a class that converts an stream to something your image class can use as a constructor or in a load method and hook them up. This is a common thing to have to figure out with Java i/o, unfortunately there is no cookbook way to do it across all images and situations, so we can't just tell you what it is.
EDIT 2:
As from the comment, try:
ImageIO.read(new File(MyClass.class.getResource("resources/image-name.png");
I set up my Eclipse projects like this.
The input directory is added to the classpath (JavaBuildPath in Eclipse).
Finally, you access the image and / or text files like this.
private BufferedImage getIconImage() {
try {
return ImageIO.read(getClass().getResourceAsStream(
"/StockMarket.png"));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
My resources folder inside my jar includes a directory with several binary files. I am attempting to use this code to extract them:
try(InputStream is = ExternalHTMLThumbnail.class.getResourceAsStream("/wkhtmltoimage")) {
Files.copy(is, Paths.get("/home/dan/wkhtmltoimage");
}
This is throwing the error
java.nio.file.NoSuchFileException: /home/dan/wkhtmltoimage
Which comes from
if (errno() == UnixConstants.ENOENT)
return new NoSuchFileException(file, other, null);
in UnixException.java. Even though in Files.java the correct options are passed:
ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE);
from Files.copy. Of course there's not! That's why I'm trying to make it. I don't yet understand Path and Files enough to do this right. What's the best way to extract the directory and all its contents?
Confused because the docs for Files.copy claims
By default, the copy fails if the target file already exists or is a symbolic link
(Apparently it fails if the target file doesn't exist as well?)
And lists the possible exceptions, and NoSuchFileException is not one of them.
If you're using Guava:
URL url = Resources.getResource(ExternalHTMLThumbnail.class, "wkhtmltoimage");
byte[] bytes = Resources.toByteArray(url);
Files.write(bytes, new File("/my/path/myFile"));
You could of course just chain that all into one line; I declared the variables to make it more readable.
The file that does not exist may actually be the directory you're trying to create the file in.
/home/dan/wkhtmltoimage
Does /home/dan exist? Probably not if you're on a Mac.
Android seems to make life pretty easy for loading resources of certain types. Once I leave the beaten path a little bit, it seems less helpful. I can load in images, sounds and other objects from the assets folder if and only if they are of certain types. If I try to load a binary file of my own format, I get a less than helpful 'file not found' exception, even though listing the directory shows that it is clearly there.
I've tried using the following methods to read a binary file of a custom format from the assets directory:
File jfile = new File("file://android_asset/"+filename); //tried to get the URI of the assets folder
JarFile file = new JarFile("assets/"+filename); //tried assuming the assets folder is root
fd = am.openNonAssetFd( filename); //tried getting my file as an non asset in the assets folder (n.b. it is definitely there)
fs = am.open(filename, AssetManager.ACCESS_BUFFER); //tried loading it as an asset
I'm thinking that there's something fundamental about android file I/O that I don't understand yet. The documentation for asset management seems incomplete and there must be some reason for deliberately making this unintuitive (something to do with security?). So, what's the fool proof, canonical way of loading a binary file of my own format within an android app?
UPDATE:
I tried file:///android_asset/ but still no joy.
String fullfilename = "file:///android_asset/"+filename;
File jfile = new File(fullfilename);
if (jfile.exists())
{
return new FileInputStream(jfile);
}
else
{
return null; //the file does exist but it always says it doesn't.
}
Are there any permissions for the file or in the project manifest that I need?
Thanks
I think the best way to load a file from the Assets folder would be to use AssetManager.open(String filename) - this gives you back an InputStream which you can then wrap in a BufferedInputStream and otherwise call read() to get the bytes. This would work regardless of the file type. What kind of problems have you had with this approach specifically?
I think you have left out the slash as in
File jfile = new File("file:///android_asset/"+filename);
There's three forward slashes, not two. :)
For me the solution was to uninistall the application, clean the project in Eclipse and run it again. The problem was Android couldn't find the new files I put in the asset folder.
I ended up reading this question so I hope this can be helpful to someone else.