Android中一些数据存储函数的封装

本文探讨了Android设备上不同存储类型(如EMMC、SD卡等)的挂载位置及如何通过代码获取各存储区域的可用空间、总空间等信息。重点介绍了在创建文件时如何检查并利用这些信息,确保文件正确存储于优先级较高的存储位置,同时解决了应用间文件权限问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本人博客原文

Android很多手机现在都有EMMC存储(一般是2G),一些手机并没有挂载在getExternalStorageDirectory()这个节点上(该节点用于挂载外部sdcard了).而是挂载到"/mnt/emmc"节点上,另外一些手机把 EMMC存储直接 挂载到了 getExternalStorageDirectory() 这个节点上,而对于真正的外部sdcard挂载到了 "/mnt/sdcard2" 这个节点上。另外 /system/etc/vold.fstab文件中描述了SD card的挂载点,我们可以读取它来得到关于 SD card的挂载点信息
因此当我们存储一个文件时首先应该存在 getExternalStorageDirectory() 这个节点上,其次是 "/mnt/sdcard2" 这个节点上,再次是 "/mnt/emmc",再次考虑 /system/etc/vold.fstab文件中的挂载点 ,最后才是手机的内部存储(即“/data”区域)。
注意:对于 /system/etc/vold.fstab文件中的挂载点,很可能就是 getExternalStorageDirectory() 这个节点上,或是 "/mnt/sdcard2" 这个节点上,或是是 "/mnt/emmc"。但是其实做两次检查应该没有什么副作用,由于对于读取 /system/etc/vold.fstab文件来得到 描述SD card的挂载点这个事情似乎不是一个官方的做法;我就把它放在了更低的优先级
另外,在很多手机上,虽然我们使用Context的 openFileOutput(FILENAME, Context. MODE_WORLD_READABLE ) 的方式来创建文件,而且使用ls -l看到该文件对别的应用程序来说其实已经有读的权限,但是别的应用程序实际上还是无法读取这些。这时我们需要在创建该文件的应用程序中对 getFilesDir() 目录执行"chmod 705"的操作来解决该问题。
我特把这些操作进行封装,以便使用。
 
  

package cn . edu . cdut . robin ;
import java . io . File ;
import java . io . IOException ;
import android . content . Context ;
import android . os . Environment ;
import android . os . StatFs ;
import android . text . TextUtils ;
public class AppUtil {
static Context context ; static void init ( Context cxt ) { context = cxt ; } /** get external Storage available space */ public static long getExternaltStorageAvailableSpace () { if (! Environment . getExternalStorageState (). equals ( Environment . MEDIA_MOUNTED )) { return 0 ; } File path = Environment . getExternalStorageDirectory (); StatFs statfs = new StatFs ( path . getPath ()); long blockSize = statfs . getBlockSize (); long availableBlocks = statfs . getAvailableBlocks (); return blockSize * availableBlocks ; } /** get external Storage available space */ public static long getExternaltStorageTotalSpace () { File path = Environment . getExternalStorageDirectory (); StatFs statfs = new StatFs ( path . getPath ()); long blockSize = statfs . getBlockSize (); long totalBlocks = statfs . getBlockCount (); return blockSize * totalBlocks ; } /** get sdcard2 external Storage available space */ public static long getSdcard2StorageAvailableSpace () { if (! Environment . getExternalStorageState (). equals ( Environment . MEDIA_MOUNTED )) { return 0 ; } String path = getSdcard2StorageDirectory (); File file = new File ( path ); if (! file . exists ()) return 0 ; StatFs statfs = new StatFs ( path ); long blockSize = statfs . getBlockSize (); long availableBlocks = statfs . getAvailableBlocks (); return blockSize * availableBlocks ; } /** get sdcard2 external Storage total space */ public static long getSdcard2StorageTotalSpace () { String path = getSdcard2StorageDirectory (); File file = new File ( path ); if (! file . exists ()) return 0 ; StatFs statfs = new StatFs ( path ); long blockSize = statfs . getBlockSize (); long totalBlocks = statfs . getAvailableBlocks (); return blockSize * totalBlocks ; } /** get EMMC internal Storage available space */ public static long getEmmcStorageAvailableSpace () { String path = getEmmcStorageDirectory (); File file = new File ( path ); if (! file . exists ()) return 0 ; StatFs statfs = new StatFs ( path ); long blockSize = statfs . getBlockSize (); long availableBlocks = statfs . getAvailableBlocks (); return blockSize * availableBlocks ; } /** get EMMC internal Storage available space */ public static long getEmmcStorageTotalSpace () { String path = getEmmcStorageDirectory (); File file = new File ( path ); if (! file . exists ()) return 0 ; StatFs statfs = new StatFs ( path ); long blockSize = statfs . getBlockSize (); long totalBlocks = statfs . getBlockCount (); return blockSize * totalBlocks ; } static FstabReader fsReader = null ; /** get other external Storage available space*/ public static long getOtherExternaltStorageAvailableSpace () { if (! Environment . getExternalStorageState (). equals ( Environment . MEDIA_MOUNTED )) { return 0 ; } if ( otherExternalStorageState == kOtherExternalStorageStateUnable ) return 0 ; if ( otherExternalStorageDirectory == null ) { getOtherExternalStorageDirectory (); } if ( otherExternalStorageDirectory == null ) return 0 ; StatFs statfs = new StatFs ( otherExternalStorageDirectory ); long blockSize = statfs . getBlockSize (); long availableBlocks = statfs . getAvailableBlocks (); return blockSize * availableBlocks ; } private static String otherExternalStorageDirectory = null ; private static int kOtherExternalStorageStateUnknow =- 1 ; private static int kOtherExternalStorageStateUnable = 0 ; private static int kOtherExternalStorageStateIdle = 1 ; private static int otherExternalStorageState = kOtherExternalStorageStateUnknow ; public static String getOtherExternalStorageDirectory () { if ( otherExternalStorageState == kOtherExternalStorageStateUnable ) return null ; if ( otherExternalStorageState == kOtherExternalStorageStateUnknow ) { FstabReader fsReader = new FstabReader (); if ( fsReader . size ()<= 0 ) { otherExternalStorageState = kOtherExternalStorageStateUnable ; return null ; } List < StorageInfo > storages = fsReader . getStorages (); /*对于可用空间小于100M的挂载节点忽略掉*/ long availableSpace = 100 <<( 20 ); String path = null ; for ( int i = 0 ; i < storages . size (); i ++) { StorageInfo info = storages . get ( i ); if ( info . getAvailableSpace ()> availableSpace ){ availableSpace = info . getAvailableSpace (); path = info . getPath (); } } otherExternalStorageDirectory = path ; if ( otherExternalStorageDirectory != null ){ otherExternalStorageState = kOtherExternalStorageStateIdle ; } else { otherExternalStorageState = kOtherExternalStorageStateUnable ; } } return otherExternalStorageDirectory ; } public static long getInternalStorageAvailableSpace () { String path = getInternalStorageDirectory (); StatFs stat = new StatFs ( path ); long blockSize = stat . getBlockSize (); long availableBlocks = stat . getAvailableBlocks (); return blockSize * availableBlocks ; } /** * 获取手机内部总的存储空间 * * @return */ public static long getInternalStorageTotalSpace () { File path = Environment . getDataDirectory (); StatFs stat = new StatFs ( path . getPath ()); long blockSize = stat . getBlockSize (); long totalBlocks = stat . getBlockCount (); return totalBlocks * blockSize ; } public final static String getExternalStorageDirectory () { return Environment . getExternalStorageDirectory () + File . separator + "" ; } public final static String getExternalStoragePublicDirectory ( String type ) { return Environment . getExternalStoragePublicDirectory ( type ) . getAbsolutePath (); } public final static String getSdcard2StorageDirectory () { return "/mnt/sdcard2" ; } public final static String getEmmcStorageDirectory () { return "/mnt/emmc" ; } private static String externalStoragePrivateDirectory ; static String getExternalPrivateFilesDirectory () { if ( externalStoragePrivateDirectory == null ) externalStoragePrivateDirectory = context . getExternalFilesDir ( null ) . getAbsolutePath (); return externalStoragePrivateDirectory ; } private static String internalStorageDirectory ; public final static String getInternalStorageDirectory () { if ( TextUtils . isEmpty ( internalStorageDirectory )) { File file = context . getFilesDir (); internalStorageDirectory = file . getAbsolutePath (); if (! file . exists ()) file . mkdirs (); String shellScript = "chmod 705 " + internalStorageDirectory ; runShellScriptForWait ( shellScript ); } return internalStorageDirectory ; } public static boolean isInternalStoragePath ( String path ) { String rootPath = getInternalStorageDirectory (); if ( path != null && path . startsWith ( rootPath )) return true ; return false ; } public static String getFileName ( String file ) { if ( file == null ) return null ; int index = file . lastIndexOf ( "/" ); return file . substring ( index + 1 ); } public static boolean runShellScriptForWait ( final String cmd ) throws SecurityException { ShellThread thread = new ShellThread ( cmd ); thread . setDaemon ( true ); thread . start (); int k = 0 ; while (! thread . isReturn () && k ++ < 20 ) { try { Thread . sleep ( 50 ); } catch ( InterruptedException e ) { // TODO Auto-generated catch block e . printStackTrace (); } } if ( k >= 20 ) { thread . interrupt (); } return thread . isSuccess (); } /** 用于执行shell脚本的线程 */ private static class ShellThread extends Thread { private boolean isReturn ; private boolean isSuccess ; private String cmd ; public boolean isReturn () { return isReturn ; } public boolean isSuccess () { return isSuccess ; } /** * @param cmd * shell命令内容 * @param isReturn * 线程是否已经返回 * @param isSuccess * Process是否执行成功 */ public ShellThread ( String cmd ) { this . cmd = cmd ; } @Override public void run () { try { Runtime runtime = Runtime . getRuntime (); Process proc ; try { proc = runtime . exec ( cmd ); isSuccess = ( proc . waitFor () == 0 ); } catch ( IOException e ) { e . printStackTrace (); } isSuccess = true ; } catch ( InterruptedException e ) { } isReturn = true ; } } public static class FstabReader { public FstabReader () { init (); } public int size () { return storages == null ? 0 : storages . size (); } public List < StorageInfo > getStorages () { return storages ; } final List < StorageInfo > storages = new ArrayList < StorageInfo >(); public void init () { File file = new File ( "/system/etc/vold.fstab" ); if ( file . exists ()) { FileReader fr = null ; BufferedReader br = null ; try { fr = new FileReader ( file ); if ( fr != null ) { br = new BufferedReader ( fr ); String s = br . readLine (); while ( s != null ) { if ( s . startsWith ( "dev_mount" )) { /*"\s"转义符匹配的内容有:半/全角空格*/ String [] tokens = s . split ( "\\s" ); String path = tokens [ 2 ]; // mount_point StatFs stat = new StatFs ( path ); if ( null != stat && stat . getAvailableBlocks () > 0 ) { long availableSpace = stat . getAvailableBlocks ()* stat . getBlockSize (); long totalSpace = stat . getBlockCount ()* stat . getBlockSize (); StorageInfo storage = new StorageInfo ( path , availableSpace , totalSpace ); storages . add ( storage ); } } s = br . readLine (); } } } catch ( Exception e ) { e . printStackTrace (); } finally { if ( fr != null ) try { fr . close (); } catch ( IOException e ) { // TODO Auto-generated catch block e . printStackTrace (); } if ( br != null ) try { br . close (); } catch ( IOException e ) { // TODO Auto-generated catch block e . printStackTrace (); } } } } } static class StorageInfo implements Comparable < StorageInfo > { private String path ; private long availableSpace ; private long totalSpace ; StorageInfo ( String path , long availableSpace , long totalSpace ) { this . path = path ; this . availableSpace = availableSpace ; this . totalSpace = totalSpace ; } @Override public int compareTo ( StorageInfo another ) { if ( null == another ) return 1 ; return this . totalSpace - another . totalSpace > 0 ? 1 : - 1 ; } long getAvailableSpace () { return availableSpace ; } long getTotalSpace () { return totalSpace ; } String getPath () { return path ; } }
}

代码2
 
   

static String getSavePath ( long saveSize ) {
String savePath = null ;
if ( AppUtil . getExternaltStorageAvailableSpace () > saveSize ) {
savePath = AppUtil . getExternalStorageDirectory ();
File saveFile = new File ( savePath );
if (! saveFile . exists ()) {
saveFile . mkdirs ();
} else if (! saveFile . isDirectory ()) {
saveFile . delete ();
saveFile . mkdirs ();
}
} else if ( AppUtil . getSdcard2StorageAvailableSpace () > saveSize ) {
savePath = AppUtil . getSdcard2StorageDirectory ();
File saveFile = new File ( savePath );
if (! saveFile . exists ()) {
saveFile . mkdirs ();
} else if (! saveFile . isDirectory ()) {
saveFile . delete ();
saveFile . mkdirs ();
}
} else if ( AppUtil . getEmmcStorageAvailableSpace () > saveSize ) {
savePath = AppUtil . getEmmcStorageDirectory ();
File saveFile = new File ( savePath );
if (! saveFile . exists ()) {
saveFile . mkdirs ();
} else if (! saveFile . isDirectory ()) {
saveFile . delete ();
saveFile . mkdirs ();
}
} else if ( AppUtil . getOtherExternaltStorageAvailableSpace ()> saveSize ) {
savePath = AppUtil . getOtherExternalStorageDirectory ();
File saveFile = new File ( savePath );
if (! saveFile . exists ()) {
saveFile . mkdirs ();
} else if (! saveFile . isDirectory ()) {
saveFile . delete ();
saveFile . mkdirs ();
}
} else if ( AppUtil . getInternalStorageAvailableSpace () > saveSize ) {
savePath = AppUtil . getInternalStorageDirectory () + File . separator ;
}
return savePath ;
}

<wbr style="line-height:25px; font-family:Arial,Helvetica,simsun,u5b8bu4f53; font-size:14px; background-color:rgb(245,245,245)"><br></wbr>
<wbr>结束</wbr>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值