What happens when I instantiate a File in Android? - java

I want to understand how the File class works in Android. For instance, with the instruction:
File file = new File(MyActivity.this.getFilesDir().toString()+File.separator+"myfile.jpg");
Is the file created during the instanciation (with a 0 kb size) or when I write into it?

A File object is actually a path to a file, not the actual file (despite the name). Think of them as glorified Strings.
You can create File objects that point to nonexistent files, files in nonexistent directories, files with invalid paths, or files you don't have access to, without problems. In any of those cases, you will get an exception when you actually try to open the file (unless it simply doesn't exist and you're writing to it; that creates the file).

Nothing happens on disk when you instantiate the file - you are just creating a file object that refers to a possibly-existent actual disk file.
If the disk file doesn't exist when you instantiate the File object, it won't exist until you create it using, for instance, createNewFile().

Related

Java FileNotFoundException when trying to read txt file from resources folder

I'm trying to read a text file located in src/main/resources/test/file.txt. I'm trying to get the path of the file using String path = getClass().getResource("/text/file.txt").getFile(); but when I try to read it I get a FileNotFoundException. I tried putting many different paths, all of which failed. How can I go about doing this?
The idea of putting something into the src/main/resources tree is that it will be copied into the JAR file that you build from your project. It will then be available to your application via the Class methods getResource(String) and getResourceAsStream(String) methods.
When you are running in your application in the development environment, it is certainly possible to use FileInputStream etcetera to access the resource. But this won't work in production. In production, the resources will then be inside your app's JAR file. FileInputStream cannot open a JAR file and its contents by name.
When you do this:
getClass().getResource("/text/file.txt");
you get a URL for the resource, which will look something like this:
jar:file:/path/to/your.jar!/text/file.txt"
It is not possible to turn that into a pathname the FileInputStream will understand. Whatever you try will give you a FileNotFoundException ... or something that is not the resource you want to read.
So what to do?
You have a few options, depending on your application's requirements.
You can use getResourceAsStream and use the resulting input stream directly.
You can copy the contents of getResourceAsStream to a temporary file, and then use the pathname of the temporary file.
You can create an application specific directory (e.g. in the user's home directory) and extract the file you need from the JAR into the directory. You might do this the first time the application runs.
You could open the JAR file as a JarFile and use that API to open an InputStream for the resource. But this assumes that that the resources are in a JAR ... and on some platforms (e.g. Windows) you may encounter problems with file locking. (And it would be a bad idea to attempt to update the resource in the JAR.)
Try giving complete path of the file from the disk.
C:\Users\MyUser\Desktop\file name with extension

Write to Properties File in Java without knowing it's path

I am loading my properties file using the class loader as follows.
Properties prop = new Properties();
prop.load(MyClass.class.getResourseAsStream("/Property.properties"));
Now, using this method I am able to read the properties file. I want to write some data to the property file. I don't know the path of the property file. How do I store the data to the property file then ?
Update
I tried the following, but it doesn't give me the correct path:
File propFile = new File("Property.properties");
System.out.println(propFile.getAbsolutePath());
I don't think you can in a generic way that would always work, because your properties file could be bundled inside a jar, etc. You can get the URL via getResource(String) and then do something with that URL, for example if it's a file URL, you could get the file name there.
URL u=MyClass.class.getResource("/Property.properties");
if ("file".equals(u.getProtocol()){
File f=new File(u.toURI());
}
But that wouldn't work in all cases.
I would write the modified value to a file in a well known location, and use the bundled Properties as the default value, that are overriden by the values in the file.
There are two parts to your question.
First, the reading part. You said: "I am loading my properties file ..." using the code you provided. This code treats the file as a "resource" and loads it using the class loader. The class loader mechanism in the Java Runtime comes into picture here. Roughly speaking, this mechanism searches for it in your application's current classpath and makes the input stream associated with first matching resource available to your code. It may be fine in your case, however, you should realize that if there are multiple properties files by the same name in different parts of your classpath (e.g. different JAR files having the same config file), then you may not know which file is being read. The only way to ensure that you are reading the right file from the classpath is to ensure that you have that config file in a unique place in your application's classpath.
This seems to work for you. Reading from a file is easier, than, say writing to a file.
In the second part, you want to write to a file. It's important to note that you should know the exact whereabouts of the file you are writing to. If you rather unknowingly convert it to an output stream, then you might end up trying to write to a stream that you are not allowed to write to. So, here, you should try to find the location (path) of the actual, physical file, for example, on a computer's hard drive. That path is something you should know before you write and run this program. Remember that a file always exists in a folder or a directory.
Your attempt:
File propFile = new File("Property.properties");
System.out.println(propFile.getAbsolutePath());
to find the location or path of the file you want to write to fails because when you do new File("Property.properties");, Java tries to refer to a file (does not do anything yet with the operating system) that resides in the Java Runtime's current working directory. This refers to the location given by System.getProperty("user.dir"). So, your propFile refers to a (hypothetical) file in that folder and the call to getAbsolutePath() prints its path. This is not the file that you want because you are trying to write to a file whose path you don't know. So, you should find the path of the file and then use a BufferedWriter backed by a FileWriter or BufferedOutputStream backed by a FileOutputStream to write to this file. Make sure that the file you want to write to exists and you have permission to write to it.
Essentially get the resource as an OutputStream, then pass it to the store() method of your Properties object.
Details here:
http://www.drdobbs.com/jvm/readwrite-properties-files-in-java/231000005

Need File or URL, referencing a folder (NOT FILE) from raw or assets

I have once again had trouble using JWI Wordnet in Android. The only way to access it, is to create a URL or File pointing to the directory where the files it needs are located. http://projects.csail.mit.edu/jwi/api/index.html I have downloaded the files I need, and added the jar into my project. My error is when I try to create the Dictionary object used to access wordnet. I don't point to a valid directory. Which makes sense, but I just don't know how to do so pointing the correct way. Basically, the folder name is "dict", I can place it into either raw or Assets (Although I read something about files in assets needing to be < 1 mb, the files inside the folder are greater than 1 mb) I need to create either a File or URL that points to said folder. How would I go about doing this?
So, you cannot create a file from raw or assets directly, as they are not stored as files, but you can copy/unpack them somewhere else, and make a File object using the copy. Android: how do I create File object from asset file?

"URI is not hierarchical" when loading resource

I need the URI of a file (which I put in the resources directory). If I use
MyClass.class.getClassLoader().getResource(resource)
I get
java.lang.IllegalArgumentException: URI is not hierarchical
Otherwise, if I use ClassLoader.getSystemResource(resource) it returns null.
Are you loading the file from inside a jar? If so, the OS is unable to form a java File instance from inside a jar. To be able to load it, try open it as a Stream. "filepath" should start with a "/".
MyClass.class.getClass().getResourceAsStream( filepath );
You should be using
getResourceAsStream(...);
when the resource is bundled as a jar/war or any other single file package for that matter.
See the thing is, a jar is a single file (kind of like a zip file) holding lots of files together. From Os's pov, its a single file and if you want to access a part of the file(your image file) you must use it as a stream.

OpenNI: Recorder create function and .oni file creation

This might be a silly question but I am new to OpenNI. Using the OpenNI-Linux-x86-2.2 package.
When I use Recorder.create(String filename), does it create the file or use a pre-existing file? I am asking because I can't find anything which creates .oni files other then making a blank file with .oni suffix (which feels risky).
If it uses a pre-existing .oni file, how do I create one?
The API seems unclear.
Also, is filename just the name without the .oni suffix? (as in, always same directory and not relative/absolute filepath or something)
After playing with it a little I reached the following:
filename is the file path just like when creating java.nio.File objects using the File(String pathname) constructor
If no such file exists, it creates one.
It works even if a pre-existing file is already there, did not get around to testing if it overwrites it or if it writes at beginning/end

Categories