【问题标题】:OutputStream issue...OutofBoundsExceptionOutputStream 问题...OutofBoundsException
【发布时间】:2017-08-04 15:00:55
【问题描述】:

我对 Android 还是很陌生,正在制作一个需要从 url 下载并缓存 jpg 以供使用的应用程序。

到目前为止,我从多个参考资料(以及我自己的修补)中得到了这个:

public class download_image extends AsyncTask<String, Void, String> {
    int count;
    @Override
    protected String doInBackground(String... urls) {
        try {
            String root = getFilesDir().toString();
            URL imgurl = new URL(urls[0]); // Form a URL object from string.
            URLConnection c = imgurl.openConnection();   //Open connection.
            int length_of_file = c.getContentLength();      // Get size of target jpg
            Log.v("Background Response","Length fo target img = "+length_of_file);
            InputStream i = new BufferedInputStream(imgurl.openStream(),length_of_file);

            //Make target image file...
            final File image = new File(getApplicationContext().getCacheDir().toString(),"image.jpg");

            OutputStream o = new FileOutputStream(image);
            byte data[] = new byte[length_of_file];
            long total = 0;
            while ((count = i.read(data))!=1){
                total+=count;
                o.write(data,0,count);
            }

            o.flush();
            o.close();
            i.close();

        } catch (MalformedURLException m) {
            Log.e("Exception", m.toString());
        } catch (IOException i) {
            Log.e("Exception", i.toString());
        }

        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        System.out.println("Downloaded");
        super.onPostExecute(s);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }
}

问题似乎是数组 data[] 溢出还是什么? 我不太明白。我尝试使 InputStream 的缓冲区等于 length_of_file = getContentLength(); 中的文件大小;

任何帮助将不胜感激! 到目前为止,我很高兴地解决了其他问题(比如获取要写入的内部文件夹以及异步任务是什么......我最初不知道我需要 HTTPConnections)。

    08-04 15:51:22.938 13454-13486/com.example.johnny.fibre V/Background Response: Length fo target img = 106620
08-04 15:51:23.058 13454-13486/com.example.johnny.fibre E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
                                                                          Process: com.example.johnny.fibre, PID: 13454
                                                                          java.lang.RuntimeException: An error occurred while executing doInBackground()
                                                                              at android.os.AsyncTask$3.done(AsyncTask.java:325)
                                                                              at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                                                                              at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                                                                              at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                                                                              at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
                                                                              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
                                                                              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
                                                                              at java.lang.Thread.run(Thread.java:761)
                                                                           Caused by: java.lang.ArrayIndexOutOfBoundsException: length=106620; regionStart=0; regionLength=-1
                                                                              at java.util.Arrays.checkOffsetAndCount(Arrays.java:4857)
                                                                              at libcore.io.IoBridge.write(IoBridge.java:490)
                                                                              at java.io.FileOutputStream.write(FileOutputStream.java:316)
                                                                              at com.example.johnny.fibre.Home$download_image.doInBackground(Home.java:476)
                                                                              at com.example.johnny.fibre.Home$download_image.doInBackground(Home.java:456)
                                                                              at android.os.AsyncTask$2.call(AsyncTask.java:305)
                                                                              at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                              at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
                                                                              at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
                                                                              at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
                                                                              at java.lang.Thread.run(Thread.java:761) 

【问题讨论】:

    标签: android inputstream indexoutofboundsexception outputstream


    【解决方案1】:

    getContentLength() 返回length of the content header,而不是您正在下载的图像的大小。在这种情况下,很可能您分配的数组不够大,无法容纳您要写入的图像!

    与其分配byte 数组,不如将您读取的数据流式传输到ByteArrayOutputStream,并在完成后通过在流上调用getBytes() 来获取结果?

    通过这种方式,您根本不需要知道图像的长度;您需要做的就是继续读取数据,直到到达InputStream 的末尾。

    Click here for an example of how to use a ByteArrayOutputStream.

    作为替代方案,您可能希望利用 Android 运行时内置的一些 helper utilities,专门用于从 URL 获取图像数据。

    【讨论】:

    • 谢谢。如果我有任何问题,我会查看 ByteArrayOutputStream 并返回。我想缓存图像以供将来使用,而不是每次需要图像时都必须使用活动的 Internet 套接字......所以 Helper Utilities 似乎已经用完了。
    • 如果你使用我引用的帮助工具,你可以在初始化时进行一次在线调用,或者在第一次需要时,将图像的引用存储在本地模型中,这样你就不会必须不断查询网络。
    猜你喜欢
    • 2012-02-25
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    相关资源
    最近更新 更多