I am attempting to parse a json file as part of an android development project. Here is the error message that keeps popping up:
W/System.err: java.nio.file.NoSuchFileException: C:/Users/andno/Desktop/AndroidDev2ClimateApp/app/src/main/java/com/example/androiddev2climateapp/ui/home/test.json
However, in android studios, the path in the error is supplied as a link, which I can click, leading me to the write file- thus, I don't think the path is wrong.
Here is my code:
String first = "C:/Users/andno/Desktop/AndroidDev2ClimateApp/app/src/main/java/com/example/androiddev2climateapp/ui/home/test.json";
try {
String fileContents = new String((Files.readAllBytes(Paths.get(first))));
JSONObject json = new JSONObject(fileContents);
JSONArray widgets = new JSONArray("WidgetArray");
for(int i = 0; i < widgets.length(); i++){
int id = widgets.getJSONObject(i).getInt("id");
System.out.println(id);
}
} catch(IOException | JSONException e){
e.printStackTrace();
}
Sorry that the formatting is messed up. I have tried using \ in the path instead of / as well, but it doesn't work. Any help would be greatly appreciated- thanks so much!
You may be able to get this code to work when you're testing, but obviously, there is no C:\Users\andno on your android phone and there never will be.
You're barking up the wrong tree. You don't want to read a file at all.
You want to read a resource from the same place java (or, rather, android) is loading the class file (or whatever passes for class file in android). Which is probably from within a jar or apk or whatnot.
UiMain.class.getResource("test.json")
or
UiMain.class.getResourceAsStream("test.json")
will get you a resource named test.json from the same place that UiMain.class is located (i.e. in the same package, I'm assuming this is class com.example.android.androiddev2climateapp.home.ui.UiMain. The first one as a URL, which you can usually pass to constructors of images and the like, and the second as stream, which you'd need to safely close (try/finally or try-with-resources if android has gotten around to adding that 20 year old java feature already), and which you can turn into a string using various APIs. Probably the JSON API itself can just be fed an inputstream.
Related
I was wanting to create a android application where I could quickly write basic java code and get it to output in a TextView. I originally got this idea up and running messing around in intellij and thought it would be a cool app so I started building it in android studio. What I was planning to do was create a 'dummy' java file, parse my code into the file, then execute the file. That way java would do all of the heavy lifting.
I am a student so I want this app as a way to practice writing sorting algorithms/recursive functions... basically the stuff they ask you to program in job interviews. I should also mention that this is research for my final school project.
Here is what I have already tried to do.
I have added permission in my manifest
< uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/ >
and this is how I am trying to create the file.
String FILENAME = "Interpreter.java";
String string = "hello world!";
try {
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
}catch(Exception e){
}
I do not know where the file is being created if at all...
Am i going in the right direction? does anyone know if this is even possible in android?
Thank you in advance!
I have 80,000 words for a crossword (among others) puzzle word pattern matcher. (User inputs "ba??" and gets, among other things, "ball, baby, bank, ..." or enters "ba*" and gets the aforementioned as well as "bat, basket, babboon...".)
I stuck the words in a Netbeans "empty file" and named it "dictionary". The file's contents are just (80,000) words, one per line. This code works like a charm to read the dictionary (code that filters is omitted):
static void showMatches(String pattern, String legal, String w) throws IOException
{
Path p = Paths.get("C:\\Users\\Dov\\Documents\\NetBeansProjects\\Masterwords\\src\\masterwords\\dictionary");
String word;
Scanner sc = new Scanner(p).useDelimiter("\r");
while(sc.hasNext()){
word = sc.next().substring(1);
gui.appendOutput(word);
}
sc.reset();
}
Is there a way to make the file (named "dictionary") become part of the compiled jar file so that I only need to "ship" one file to new, (largely helpless) users?
In another matter of curiosity...
Is it possible to make the argument to Paths.get(...) something like "masterwords/src/dictionary" to make the connection for the Scanner object to be able read it? I'm wondering if this might relate to an answer my first question. (If there's a way, I can't stumble onto it. Whatever similar string I use, I get no error, no output, no "build successful"--gotta click Run > Stop build/run.)
I'm not certain, based on your description, that my solution addresses your issue, but let me restate the problem as I understand it: You have a .jar file that relies on a dictionary resource. That resource is subject to change, and you'd like to be able to update it without having to ship out a whole new .jar containing a new dictionary.
If I'm reading you correctly, you want something like:
private File getInstallPath()
{
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
}
This will return the install directory of your .jar file, which is where you can put your dictionary resource so that the .jar knows where to find it. Of course, now you have a bit of a training issue, because users can move, delete or misplace your dictionary file.
Part II:
Now that you've clarified your question, let me again restate: You want to be able to read an arbitrary file included in your .jar file. Fine. You're probably trying to open the file as a file, but once the file is in your .jar, you need to treat it as a resource.
Try using:
Class myClass = Class.forName("MyClass");
ClassLoader myLoader = myclass.getClassLoader();
InputStream myStream = myLoader.getResourceAsStream(myFile);
Do you really need me to explain what "myClass," "myLoader," etc. refer to? Hint: "myClass" is whatever your class is that needs to read the file.
After leaving this thread in frustration for a couple of weeks, yesterday I found a similar question at this forum, which led me to Google "java resource files" and visit ((this URL)).
Between the two I figured out how to read a file named 'dictionary' that was created as a Netbeans "empty Java file", which was located in Source Packages ... [default package] (as shown in Netbeans Projects window) and stored as C:\Users\Dov\!Docs\Documents\NetBeansProjects\WordPatternHelp\src\dictionary:
File file = new File("src/dictionary");
...
p = file.toPath();
sc = new Scanner(p).useDelimiter("\r");
Success. Hooray.
But after compiling and executing the .jar file from a DOS command line, 'dictionary' couldn't be found. So the above only works from within Netbeans IDE.
After mostly erroneous attempts caused by the above 'success', I finally got success using #Mars' second suggestion like so:
package masterwords;
public class Masterwords
...
InputStream myStream = Class.forName("masterwords.Masterwords").
getClassLoader().getResourceAsStream("dictionary");
sc = new Scanner(myStream).useDelimiter("\r"); // NULL PTR EXCEPTION HERE
So, for whatever it might be worth, a very belated thanks (and another apology) to #Mars. It was as straightforward as he indicated. Wish I'd tried it 2 weeks ago, but I'd never seen any of the methods and didn't want to take the time to learn how they work back then with other more pressing issues at hand. So I had no idea Mars had actually written the exact code I needed (except for the string arguments). Boy, do I know how the methods work now.
I'm using Eclipse (SDK v4.2.2) to develop a Java project (Java SE, v1.6) that currently reads information from external .txt files as part of methods used many times in a single pass. I would like to include these files in my project, making them "native" to make the project independent of external files. I don't know where to add the files into the project or how to add them so they can easily be used by the appropriate method.
Searching on Google has not turned up any solid guidance, nor have I found any similar questions on this site. If someone knows how to do add files and where they should go, I'd greatly appreciate any advice or even a point in the right direction. Also, if any additional information about the code or the .txt files is required, I'll be happy to provide as much detail as possible.
UPDATE 5/20/2013: I've managed to get the text files into the classpath; they're located in a package under a folder called 'resc' (per dharam's advice), which is on the same classpath level as the 'src' folder in which my code is packaged. Now I just need to figure out how to get my code to read these files properly. Specifically, I want to read a selected file into a two-dimensional array, reading line-by-line and splitting each line by a delimiter. Prior to packaging the files directly within the workspace, I used a BufferedReader to do this:
public static List<String[]> fileRead(String d) {
// Initialize File 'f' with path completed by passed-in String 'd'.
File f = new File("<incomplete directory path goes here>" + d);
// Initialize some variables to be used shortly.
String s = null;
List<String> a = new ArrayList<String>();
List<String[]> l = new ArrayList<String[]>();
try {
// Use new BufferedReader 'in' to read in 'f'.
BufferedReader in = new BufferedReader(new FileReader(f));
// Read the first line into String 's'.
s = in.readLine();
// So long as 's' is NOT null...
while(s != null) {
// Split the current line, using semi-colons as delimiters, and store in 'a'.
// Convert 'a' to array 'aSplit', then add 'aSplit' to 'l'.
a = Arrays.asList(s.split("\\s*;\\s*"));
String[] aSplit = a.toArray(new String[2]);
l.add(aSplit);
// Read next line of 'f'.
s = in.readLine();
}
// Once finished, close 'in'.
in.close();
} catch (IOException e) {
// If problems occur during 'try' code, catch exception and include StackTrace.
e.printStackTrace();
}
// Return value of 'l'.
return l;
}
If I decide to use the methods described in the link provided by Pangea (using getResourceAsStream to read in the file as an InputStream), I'm not sure how I would be able to achieve the same results. Would someone be able to help me find a solution on this same question, or should I ask about that issue into a different question to prevent headaches?
You can put them anywhere you wish, but depends on what you want to achieve through putting the file.
A general practice is to create a folder with name resc/resource and put files in it. Include the folder in classpath.
You can store the files within a java package and read them as classpath resources. For e.g. you can add the text files to a java package say com.foo and use this thread to know how to read them: How to really read text file from classpath in Java
This way they are independent of the environment and are co-packaged with code itself.
Add the files in the projects classpath.(you can find the class path of the project by right click the project in eclipse->Build Path->configure build path)
I guess you want an internal .txt file.
Package Explorer => Right Click at your project => New => File . Then text a file name and Finish it.
The path in your code should look like this:
Scanner diskScanner = new Scanner(new File("YourFile"));
I have a file called Gate.IC inside my assets in my Android App.
I use this code to measure the length of the file in the assets:
private byte[] Buf = new byte[1024*512];
public int FileLength (String s)
{
int Count = 0;
try {
InputStream s2 = assetManager.open(s);
int tmp = 0;
while ((tmp=s2.read(Buf))>0)
Count+=tmp;
s2.close();
}
catch (IOException e) {
String Message = e.getMessage();
}
return Count;
}
This code works fine for all files except this one.
When it gets to this file, it does open it(and shows the correct file length), but when it reads it I get an IOException and the LogCat says "Error reading asset data" and then "Unable to access asset data: -1"
If I take a different file and change it's name to Gate.IC and don't have the actual Gate.IC file in the assets, it works.
If I change the name of the original Gate.IC into another asset's name, then I get the same error with the "cover" name.
I don't know what it is in this file that it just can't read it.
Here is the Rogue file:
https://dl.dropbox.com/u/8025882/RPG/Gate.IC
you can use this for getting length of the file:
getAssets().openFd( "filename" ).getLength();
I have solved the issue.
Well as I mentioend, it turns out ADT or the Android SDK packaging would compress some fo the assets. My file being my own custom format would be compressed.
Once your file is compressed you cannot read it the same way I did.
There is a program in Android SDK called aapt.exe. It does the packaging of the assets.
All you need to do is call this command with the flag -0 .
Sounds simple, right?
The issue is that eclipse does not let you add flags to this command from within the ADT plugin.
You need to either edit the Android SDK XML build files, or to replace aapt.exe with your own program that calls the original aapt.exe program with the flags you want.
I did the latter.
Here is my devblog entry about it.
http://pompidev.net/2012/10/27/unable-to-access-asset-data-1-and-compressed-assetsandroid/
I am in the process of making a program, which allows you to view your file system.
I was testing it, and ran into a problem: It was saying a directory called "Documents and Settings" was on my C:\ drive, while it wasn't there.
This is how I get my file array:
File f = new File(path); //path being a path sent by the client, for example C:\
if(f.isFile()){
//TODO start downloading it.
out.println("ERR: no dir!");
return;
}
Server.log.log("System path requested: " + f.getAbsolutePath());
File[] files = f.listFiles();
for(int i = 0; i < files.length; i++){
File found = files[i];
if(!found.exists()){
continue;
}
if(found.isDirectory()){
out.println("dir:" + found.getName());
}else{
out.println(found.getName());
}
System.out.println("Printed " + found.getName());
}
out.println("ENDOFLIST"); //Notify the client it has to stop receiving data
For some reason, this outputs quite a lot of directories that I can't seem to find, even with the "Show hidden folders" option on.
When trying to access these directories, it tries to read the contents of the directory, but since the directory doesn't exist it throws an exception, causing no data to get sent over sockets and my client freezing.
My question is: Is there a way to either check if the file/directory REALLY exists? Note, if you look at my code block, if the file/dir doesn't exist it already continues instead of writing it to the socket.
I've given it a google, but no matches were found. Also, I've given the search function a go, but it didn't come up with anything similar.
These are hidden system folders.
They do exist. Really.
You get exceptions because a lot of them don't have read access.
I suggest to use the new Fil I/O API introduced by Java 7, it features greatly improved support of the features a specific file system offers. It also offers the possibility to use walk the file tree.
Have a look at the FileVisitor http://docs.oracle.com/javase/7/docs/api/java/nio/file/FileVisitor.html that will greatly help you.