1

I'm trying to load a JSON from webservice and write it to a file using the following code:

File cacheDir = new File(context.getCacheDir(), "texts");
cacheDir.mkdirs();
File cacheFile = new File(cacheDir, "" + articleId);
try {
    if (!cacheFile.exists()) {
        try {
            HttpURLConnection c = (HttpURLConnection) new URL(url).openConnection();
            try {
                InputStream in = c.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));

                // this approach fails
                /*
                BufferedWriter writer = new BufferedWriter(new FileWriter(cacheFile.getAbsolutePath()));

                String line = null;
                while ((line = reader.readLine()) != null) {
                    writer.write(line);
                    writer.newLine();
                }
                writer.flush();
                reader.close();
                writer.close();
                */

                // this approach works
                Gson g = new Gson();
                Article article = g.fromJson(reader, Article.class);
                String json = g.toJson(article);

                PrintWriter out = new PrintWriter(new FileWriter(cacheFile.getAbsolutePath()));
                out.print(json);

                out.flush();
                out.close();
                reader.close();

            } catch (IOException e) {
                Log.e(getClass().getSimpleName(), "Exception parsing JSON", e);
            } finally {
                c.disconnect();
            }
        } catch (Exception e) {
            Log.e(getClass().getSimpleName(), "Exception parsing JSON", e);
        }
    }
}

I've checked with adb shell and Android Monitor file browswer and the files seem to be created:

enter image description here

However, when I do cat filename from adata/data/appdir/cache no file content is printed (only command is printed again cat filename). What is wrong with my approach?

15
  • is your device rooted ? Commented May 5, 2015 at 7:29
  • I think yes, it's an emulator from Genymotion Commented May 5, 2015 at 7:30
  • get rid of cacheFile.exists(). Try debugging the content of the reader. Add some log to see if you are getting data back from the server. Do you have the internet permission ? Commented May 5, 2015 at 7:33
  • @Blackbelt, yes, content from the server comes OK, because I show it the first time if the file doesn't exist and it's displayed. It's second time when I see that the file exists I read from the file and not from the web. How would you advice me to debug it? Commented May 5, 2015 at 7:38
  • just add Log.d("TEST", ": " + line) in the while loop and read the output Commented May 5, 2015 at 7:39

2 Answers 2

1

Instead of use readLine to read from the InputStream, try with read and a char[]

if (in != null) {
    StringBuffer stringBuffer = new StringBuffer();
    final char[] charBuffer = new char[8 * 1024];
    reader = new BufferedReader(new InputStreamReader(in), charBuffer.length);
    int read;  
    while ((read = reader.read(charBuffer)) != -1) {
         stringBuffer.append(charBuffer, 0, read);
    }
    PrintWriter out = new PrintWriter(new FileWriter(cacheFile.getAbsolutePath()));
    out.print(stringBuffer.toString());
    out.flush();
    out.close();
    reader.close();
    Gson g = new Gson();
    Article article = g.fromJson(stringBuffer.toString(), Article.class);
}
Sign up to request clarification or add additional context in comments.

5 Comments

fos.write(charBuffer, 0, read); here I get the error Wrong first argument - Found char[], required byte[], why is it there?
My bad. Change char[] to byte []
A bit of your help please... after I've read from buffer with read = reader.read(charBuffer)) != -1 I pass the reader to Gson and do the followign Article article = g.fromJson(reader, Article.class);, however fromJson returns null, as if there is nothing to read from a reader. Is this a valid case to read from a reader and then pass it to the other method to work with it?
you can't reuse the reader again. Using the StringBuffer should fix it. I'll update my answer
I see, that's what I thought. Thanks a lot! Best luck!
1

You are doing all the operations inside

if (!cacheFile.exists()) {
   //your code here
}

The file.exists() method returns true if a file denoted by the path exists. So in effect what you are saying is 'do my operations if the file does not exist' which does not make sense.

Instead you could

if (!cacheFile.exists()) {
    cacheFile.createNewFile() 
}
//do the rest of your stuff here

4 Comments

Actually 'do my operations if the file does not exist' does make sense to me - if we don't have a copy of this file locally fetch it from the web - else use the cached version.
@Maximus - so you realise if there was something wrong with the code the first time you ran it the files now exists so you need to manually delete them each time in order to retest your debugged code?
The exists() method is misplaced IMO. An error in this method will create a file and after that it will never be written to because of the exists() clause. A good option would be to destroy() the file on error.
@Elemental, yeah, it's a test code, I'm going to clean it up when it's working :). Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.