1

I'm trying to get save a text file from the internet into a folder in my res directory (res/files) so I can then read and interpret it. My android manifest has set the appropiate permissions but when I test it in the simulator it fails.

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

Here's the method to get the file:

public void getTextFile(){
    String path ="http://hullmc.org.uk/cjvize/test.txt";
    URL u = null;
    try {
        u = new URL(path);
        BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream()));
        int i = 0;
        String replicated = "";
        do{
            String str = in.readLine();
            replicated = replicated + "/n" + str;
            i++;
        }while(i<85);
        in.close();
    }
    catch(Exception e){
        welcome.setText("Failed");
    }
}

Can anyone suggest why this is not working? Many thanks!

user3410162
  • 11
  • 1
  • 2

2 Answers2

1

This is working fine for me :

Use of class variable for View and Activity allow to keep code centralaized and shared, passing view as parameter, updated in constructor :)

1) Code to store the file locally

View newReport;
Activity reportActivity;    

private void downloadFile(String fileUrl, String fileName) {
    try{
        InputStream is = (InputStream) new URL(fileUrl).getContent();            
        FileOutputStream output = reportActivity.openFileOutput(fileName, newReport.getContext().MODE_PRIVATE);
        byte data[] = new byte[1024];
        int count;
        while ((count = is.read(data)) != -1)
            output.write(data, 0, count);
        output.flush();
        output.close();
        is.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

It saves the file on the internal storage.

Then to save a file from URL, just call:

      downloadFile(myFileUrl, mySaveToFileName);

And to list your local files available:

        String[] fileList = newReport.getContext().fileList();
        for (String s : fileList){
            System.out.println("File found : "+s);
        }

Note: you do not require to save it locally to read it. If you prefer just to read it (to extract some info), let me know.

2) Code to "read and save to database", this should resolve:

// After InputStream declaration:
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
while ((inputLine = in.readLine()) != null) 
 {
   //TODO Update database row concatenating inputLine to existing text value.
}
in.close();
in=null;
is.close();
Cedric Simon
  • 4,571
  • 4
  • 40
  • 52
  • Thanks for your response! I'll give it a try and hopefully I'll be on my way. The text file I suppose doesn't need to be stored locally, it's just a dump of a database that will be inserted into a SQLite db on the app. – user3410162 Mar 12 '14 at 21:00
  • I edited the answer to show you how to convert the stream to a String. Did not test it but should work :S – Cedric Simon Mar 12 '14 at 21:05
  • That's great - thanks Cedric! Are 'newReport' 'reportActivity' variables you've defined elsewhere in your code? If so how have you initialised them? I'm getting a red line under both of them :) – user3410162 Mar 12 '14 at 21:12
  • @CedricSimon since the file size is unknown, it's not recommended to convert the inputStream to a byte array. instead, you should use a loop that reads a chunk of data for each iteration and writes the data to the file. – android developer Mar 12 '14 at 21:35
  • @androidDeveloper: thanks. I updated the code for use with String saved to database (not tested but should work). Actually I use the code to save small images. – Cedric Simon Mar 12 '14 at 22:08
  • @CedricSimon I was talking about "myBABuffer.toByteArray()" , and the fact that you read byte after byte (not as efficient as larger buffers). – android developer Mar 12 '14 at 23:05
  • @androidDeveloper: what do you propose? I am open to improvements ;) – Cedric Simon Mar 12 '14 at 23:10
  • @CedricSimon just use the normal way - use a loop that will read bytes into a buffer, and write from the buffer to the file : while ((bytesRead = inputStream.read(buffer)) != -1) outputStream.write(buffer, 0, bytesRead ); . here's how to do it with a progress bar: http://stackoverflow.com/a/3028660/878126 – android developer Mar 12 '14 at 23:18
  • anyway, i've created my own answer. hope this could help. – android developer Mar 12 '14 at 23:27
  • Code updated (and tested) using input from @androiddeveloper :D – Cedric Simon Mar 13 '14 at 13:24
1

you can't save into the resource folder of your app. you can't even store files into the assets folder.

there aren't even such folders when you install the app - they are all zipped into the APK . the res folder is a special one too, because each file there also creates a constant in the "R.java" file, so that it would be easier to reach and use. you can't reach such a thing when it's dynamic...

what you can do is to choose the right folder for you (read here), and download the file into there, using something like this :

InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(fullFilePath);
byte data[] = new byte[1024];
int count;
while ((count = input.read(data)) != -1)
   output.write(data, 0, count);
//todo close streams and handle exceptions

if you use Apache commons library, you could minimize the code to just one line:

IOUtils.copy(new BufferedInputStream(url.openStream()), new FileOutputStream(fullFilePath));
android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • You can store the file using the app's internal storage, like I did in my answer. You can then recover the file (in my cases they are images downloaded) from your app. But if the objective is to save the text in SQLite, you better do it on the fly. – Cedric Simon Mar 13 '14 at 13:33
  • @CedricSimon the question was about saving a file to the res folder : " save a text file from the internet into a folder in my res directory (res/files) " . that's why the code itself is the general one and the explanation is more important. there are plenty of ways to download files. if you use Apache commons library, you could just write IOUtils.copy(new BufferedInputStream(url.openStream()), new FileOutputStream(fullFilePath)); – android developer Mar 13 '14 at 14:30