【问题标题】:InputStream returns empty file when downloading a PDF下载 PDF 时 InputStream 返回空文件
【发布时间】:2016-06-11 03:25:37
【问题描述】:

所以我正在尝试使用 HttpURLConnection 下载 PDF 文件,并且我认为我已经使用输入和输出流完成了所有工作,但是当我打开下载的 PDF 文件时(使用 Android 中的内置文件管理器和/或 ADB),或者只是通过将其传输到 OS X 来检查它,它完全是空的,并且大小显示为 0 字节。

我尝试下载 PDF 的网站是:

http://www.pdf995.com/samples/pdf.pdf

这是我的代码

    public static void DownloadFile(final String fileURL, final File directory) {

    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            try {

                try {
                    FileOutputStream f = new FileOutputStream(directory);
                    URL u = new URL(fileURL);
                    c = (HttpURLConnection) u.openConnection();
                    c.setRequestMethod("GET");
                    //c.setRequestProperty("Content-Type", "application/pdf");
                    //c.setDoOutput(true);
                    c.connect();
                    Log.d("debugz", Integer.toString(c.getContentLength()));

                    InputStream in = c.getInputStream();

                    byte[] buffer = new byte[1024];
                    int len1 = 0;
                    while ((len1 = in.read(buffer)) > 0) {
                        f.write(buffer, 0, len1);
                    }
                    f.flush();
                    f.getFD().sync();
                    f.close();


                } catch (Exception e) {
                    e.printStackTrace();
                }


            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    thread.start();


}


public static String getPDF(String pdfurl) {

    String extStorageDirectory = Environment.getExternalStorageDirectory()
            .toString();
    File folder = new File(extStorageDirectory, "schematisktscheman");
    folder.mkdir();
    File file = new File(folder, "schemainfo.pdf");
    try {
        file.createNewFile();
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    DownloadFile(pdfurl, file);

    return null; //added return
}

在我的主要活动中:

SchedulePdfProcessor.getPDF("http://www.pdf995.com/samples/pdf.pdf");
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/schematisktscheman/schemainfo.pdf")));

编辑:我在主线程上运行了网络代码,这引发了异常。现在为下载创建一个新线程,它会获取示例 PDF (http://www.pdf995.com/samples/pdf.pdf) 并将其内容放入文件中。 感谢@greenapps!

【问题讨论】:

  • 尝试将循环条件更改为(len1 = in.read(buffer)) != -1
  • Oc.setRequestProperty("Content-Type", "application/pdf");。删除那个。您没有将 pdf 数据发送到服务器。
  • .setDoOutput(true);。删除它。你没有做输出。
  • 您可以注释这些语句,而不是在此处删除代码。现在我的 cmets 没什么意义了。
  • GetPdf() 未返回字符串。而且你用的网址和你说的不一样。

标签: android pdf inputstream httpurlconnection fileoutputstream


【解决方案1】:

首先,替换:

f.close();

与:

f.flush();
f.getFD().sync();
f.close();

这可确保在继续之前将所有内容都写入磁盘。

然后,您需要使用MediaScannerConnectionscanFile() 来获取MediaStore 以了解更新的文件。

【讨论】:

  • 我改用它摆脱了异常:sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/schematisktscheman/schemainfo. pdf")));该文件仍然是空的
  • @Zino:首先,您需要在下载后而不是之前使用scanFile()(或者可能是那个广播)。如果这样做没有帮助,请使用其他工具检查文件(例如,adb shell、DDMS/Android 设备监视器的文件管理器、设备上的文件管理器),而不是使用您的桌面操作系统。如果那里是空的,那么问题出在您的下载代码中,尽管看起来不错。
  • 我现在已经完成了,正如您在我更新的问题中看到的那样,但问题仍然存在。
【解决方案2】:

我在主线程上运行了网络代码,这引发了异常。现在为下载创建一个新线程,它会获取示例 PDF (http://www.pdf995.com/samples/pdf.pdf) 并将其内容放入文件中。

Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            try {

                try {
                    FileOutputStream f = new FileOutputStream(directory);
                    URL u = new URL(fileURL);
                    c = (HttpURLConnection) u.openConnection();
                    c.setRequestMethod("GET");
                    //c.setRequestProperty("Content-Type", "application/pdf");
                    //c.setDoOutput(true);
                    c.connect();
                    Log.d("debugz", Integer.toString(c.getContentLength()));

                    InputStream in = c.getInputStream();

                    byte[] buffer = new byte[1024];
                    int len1 = 0;
                    while ((len1 = in.read(buffer)) > 0) {
                        f.write(buffer, 0, len1);
                    }
                    f.flush();
                    f.getFD().sync();
                    f.close();


                } catch (Exception e) {
                    e.printStackTrace();
                }


            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });

    thread.start();

【讨论】:

  • ran the network code on the main thread, which threw an exception 。你应该马上告诉的。而不是“执行”,而是NetworkOnMainThreadException。并且您的应用崩溃了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 2019-04-27
  • 1970-01-01
  • 2015-07-29
  • 2019-06-21
  • 2013-01-09
相关资源
最近更新 更多