【问题标题】:Android - How to work around a "no space left on device" errorAndroid - 如何解决“设备上没有剩余空间”错误
【发布时间】:2012-03-08 08:52:45
【问题描述】:

所以我最新的应用程序遇到了这个问题,它在 logcat 中抱怨设备上没有空间来保存文件,但绝对不是这种情况,因为我可以关闭我的应用程序打开相机并拍照。其他人是如何处理这个问题的。

编辑:此方法出现错误

    private void writeFile(Bitmap bmp, File f) {
    FileOutputStream out = null;

    try {
        out = new FileOutputStream(f);
        bmp.compress(Bitmap.CompressFormat.PNG, 80, out);//<---error here
    } catch (NullPointerException e) {
        e.printStackTrace();
        Log.w("nullpointerException on image error", "nullpointer");
    } catch (FileNotFoundException e) {
        Log.w("fileNotfoundException on image error", "filenotfound");
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    finally { 
        try { if (out != null ) out.close(); }
        catch(Exception ex) {} 
    }
}

这是有关此错误的 logcat 报告:

java.io.IOException: no space left on device
at org.apache.harmony.luni.platform.OSFileSystem.write(Native Method)
at dalvik.system.BlockGuard$WrappedFileSystem.write(BlockGuard.java:171)
at java.io.FileOutputStream.write(FileOutputStream.java:300)
at android.graphics.Bitmap.nativeCompress(Native Method)
at data.ImageManager.writeFile(ImageManager.java:215)
at data.ImageManager.getBitmap(ImageManager.java:192)
at data.ImageManager.access$1(ImageManger.java:102)
at data.ImageManager$ImageQueueManager.run(ImageManager.java:290)
at java.lang.Thread.run(Thread.java:1019)

编辑:这是我在外部存储器上创建目录的方式

这就是我用来创建我认为是 sd 卡的地方的东西

    String sdState = android.os.Environment.getExternalStorageState();
    if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
        File sdDir = android.os.Environment.getExternalStorageDirectory();      
        cacheDir = new File(sdDir,"data/gr");
    }
    else
        cacheDir = context.getExternalCacheDir();

    if(!cacheDir.exists())
        cacheDir.mkdirs();


    if(sdState.equals(android.os.Environment.MEDIA_MOUNTED)){
        File adSdDir =     android.os.Environment.getExternalStorageDirectory();
        adCacheDir = new File(adSdDir,"data/ad");
    }else
        adCacheDir = context.getExternalCacheDir();

    if(!adCacheDir.exists())
        adCacheDir.mkdirs();
}

然后在我寻找或创建图像的方法中进入目录:

 private Bitmap getBitmap(ImgRequestObj ids) {
    String url = null;
    String filename = ids.objId.toString();
    File f = null;

    try{
        if(ids.objName.equals("mark")){
            url = graffMarksURL;
            f = new File(cacheDir, filename);
        }else if(ids.objName.equals("admark")){
            url = adMarksURL;
            f = new File(adCacheDir, filename);
        }



    // Is the bitmap in our cache?
    Bitmap bitmap = BitmapFactory.decodeFile(f.getPath());
    if(bitmap != null) return bitmap;

    // Nope, have to download it
    try {   
            BitmapFactory.Options bfOptions=new BitmapFactory.Options();

            bfOptions.inDither=false;                     //Disable Dithering mode

            bfOptions.inPurgeable=true;                   //Tell to gc that whether it needs free memory, the Bitmap can be cleared

            bfOptions.inInputShareable=true;              //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future


            DefaultHttpClient client;
            HttpResponse response = null;
            HttpParams params = null;// new Http parameters to be used for extra buffering room in VM
            HttpPost post = null;
            InputStream is = null;
            BufferedInputStream bis = null;
            Bitmap bmp = null;
            ArrayList<NameValuePair> nvp1 = new ArrayList<NameValuePair>();

            nvp1.add(new BasicNameValuePair("id", ids.objId.toString()));
            // - martin passing id to php script select statement
             client = new DefaultHttpClient();

            try {

                post = new HttpPost(url);
                params = post.getParams();//Setting the new Http params to post
                post.setEntity(new UrlEncodedFormEntity(nvp1));
                try{
                HttpConnectionParams.setSocketBufferSize(params, 8192);//Defining the new buffer size
                response = client.execute(post);

                }
                catch(HttpResponseException e){
                    e.getCause();
                                    }
            //Capture response from query and prepare as input
            HttpEntity entity = response.getEntity();
            // move content to Input Stream
                is = entity.getContent();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

                bis = new BufferedInputStream(is);
                try{
                bmp = BitmapFactory.decodeStream(bis, null, bfOptions);
                }finally{}

                    if( is != null )
                        try {
                            is.close();
                            //response = null;
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    //Log.w("inputstream of image closed", "for this image "+id.toString());
                    if( bis != null )
                        try {
                            //response = null;
                            bis.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    bitmap = bmp;
                    writeFile(bitmap, f);
                    try{
                        bmp = null;
                    }catch(NullPointerException e){
                        e.printStackTrace();
                    }
                    return bitmap;}
                catch(Exception e){
            e.printStackTrace();
            }
        return bitmap;
    }catch(NullPointerException e){
        e.printStackTrace();
    }
    return null;
        }

【问题讨论】:

  • 你准备的怎么样了File f
  • 你如何构建文件 f 的路径?如果您不小心,您可能正在使用内部存储空间,该存储空间可能会在不影响平台相机的情况下被填满。
  • 我正在使用上面添加的代码。

标签: android out-of-memory ioexception


【解决方案1】:

您实际上是通过在 else 语句中使用 getCacheDir() 来使用内部存储器。但是,如果您想存储大数据,建议使用getExternalCacheDir(),因为并非所有安卓手机都有巨大的内部存储空间,但它们确实/可能有更大的外部存储空间。

if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) { 
   File sdDir = context.getExternalCacheDir();
   cacheDir = new File(sdDir,"data"); 
} 
else 
   Log.e("storage", "SD card not found");

【讨论】:

  • 那没有用:(我删除了我的应用程序的所有数据并卸载了它,然后使用你建议我尝试运行它,但它仍然最终在内部存储器上创建文件。同样尽快由于图像最多约 60 张,我无法再次拍照。
  • 这次你用的是getExternalCacheDir()吗?
  • 只需将所有 getCacheDir() 替换为 getExternalCacheDir() 并试一试
  • 嘿,感谢您朝着正确的方向前进。我最终使用它来使它工作....---> context.getExternalFilesDir(sdState);
【解决方案2】:

我最终将创建目录的代码更改为以下内容:

  String sdState = android.os.Environment.getExternalStorageState();
    if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
        File sdDir = android.os.Environment.getExternalStorageDirectory();      
        cacheDir = new File(sdDir,"data/gr");
    }
    else
        cacheDir = context.getExternalFilesDir(sdState); <--changed

    if(!cacheDir.exists())
        cacheDir.mkdirs();


    if(sdState.equals(android.os.Environment.MEDIA_MOUNTED)){
        File adSdDir = android.os.Environment.getExternalStorageDirectory();
        adCacheDir = new File(adSdDir,"data/ad");
    }else
        adCacheDir = context.getExternalFilesDir(sdState); <--changed

    if(!adCacheDir.exists())
        adCacheDir.mkdirs();
}

到目前为止,使用它我可以再次保存我用相机拍摄的图像,并下载我所在地区的所有图像。

【讨论】:

    猜你喜欢
    • 2010-12-05
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2017-05-06
    • 1970-01-01
    • 2021-06-16
    相关资源
    最近更新 更多