ullstrm
ullstrm

Reputation: 10160

Save PDF from InputStream

I have a problem with my code. I'm trying to save a PDF from an url. The PDF is there but its length is zero. The inputstream-length is correct though. Why ain't the PDF getting saved correctly?

This is the actual code for saving the PDF from the stream:

    public void createExternalStoragePrivateFile
                            (String name, String extension, InputStream is) {
    // Create a path where we will place our private file on external
    // storage.
    File file = new File
                     (mContext.getExternalFilesDir(null), name +"."+extension);

    try {
        Log.d("", "before: " + file.getPath() + 
                             " " + file.getTotalSpace() + "  " + file.length());
        OutputStream os = new FileOutputStream(file);
        byte[] data = new byte[is.available()];
        is.read(data);
        os.write(data);
        is.close();
        os.close();

        Log.d("","after: " + file.getPath() + 
                              " " + file.getTotalSpace() + "  " + file.length());
    } catch (IOException e) {
        // Unable to create file, likely because external storage is
        // not currently mounted.
        Log.w("ExternalStorage", "Error writing " + file, e);
    }

the output gives me this (the length is zero before and after, but the total space is not zero after. Why is the length zero?

04-25 09:38:44.938: D/(4103): before: /storage/emulated/0/Android
                                  /data/what.to.use.myapp/files/Lolpdf.pdf 0  0

04-25 09:38:44.946: D/(4103): after: /storage/emulated/0/Android
                        /data/what.to.use.myapp/files/Lolpdf.pdf 14311309312  0

Upvotes: 0

Views: 1846

Answers (1)

Mark Allison
Mark Allison

Reputation: 21909

The InputStream.available() method will not necessarily return the size of the file being downloaded, it will return what is available without making any network calls, so is likely to be returning 0. A better approach would be to allocate a small buffer, and keep reading until you reach the end:

byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
    os.write(buffer, 0, len);
}

This will be much more memory efficient as it does not require you to allocate enough memory to hold the entire document that you're downloading, and it avoids the available() method which is not returning what you're expecting it to.

Upvotes: 2

Related Questions