Android知识点梳理--sdcard读写操作

本文介绍了Android中SDcard的文件读写操作,包括权限设置、路径获取、文件操作以及读写示例代码。同时,提到了从resource的raw和asset中读取文件的方法,并提供了获取扩展存储设备大小的示例。

从事Android开发也很长时间了,知识点多而杂,一直以来都想做个系统的整理和总结,心动不如行动。

做软件开发,不管什么系统下的,总是少不了文件的读写操作,就先从SDcard的文件读写操作开始吧。

1权限

读写SDcard自然是需要从系统那获取相应的许可的,就是权限。这个是第一步,没有这个什么都做不下去。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
读写SDcard的时候经常打交道的一个类就是Environment类,列一下常见静态方法:

  1:getDataDirectory() 获取到Android中的data数据目录(sd卡中的data文件夹)     2:getDownloadCacheDirectory() 获取到下载的缓存目录(sd卡中的download文件夹)     3:getExternalStorageDirectory() 获取到外部存储的目录 一般指SDcard(/storage/sdcard0)     4:getExternalStorageState() 获取外部设置的当前状态 一般指SDcard,比较常用的应该是 MEDIA_MOUNTED(SDcard存在并且可以进行读写)还有其他的一些状态,可以在文档中进行查找。

    5:getRootDirectory()  获取到Android Root路径

2判断SDcard是否存在

这个也是先决条件,很多初学者会忘记的。

/**
 * 判断sd卡是否存在,[当没有外挂SD卡时,内置ROM也被识别为存在sd卡]
 * @return
 */
private static boolean isExitSDcard(){
    boolean isExit;
    isExit = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    return isExit;
}
这里又有Environment类里的常量了,我总结了一下,在这里列出来供大家参考
MEDIA_BAD_REMOVAL 在没有挂载前存储媒体已经被移除。
MEDIA_CHECKING 正在检查存储媒体。
MEDIA_MOUNTED 存储媒体已经挂载,并且挂载点可读/写。
MEDIA_MOUNTED_READ_ONLY 存储媒体已经挂载,挂载点只读。
MEDIA_NOFS 存储媒体是空白或是不支持的文件系统
MEDIA_REMOVED 存储媒体被移除。
MEDIA_SHARED 存储媒体正在通过USB共享。
MEDIA_UNMOUNTABLE 存储媒体无法挂载。
MEDIA_UNMOUNTED 存储媒体没有挂载。

在Environment中还提供了Android标准目录的路径,以String类型提供。
DIRECTORY_ALARMS 系统提醒铃声存放的标准目录。
DIRECTORY_DCIM 相机拍摄照片和视频的标准目录。
DIRECTORY_DOWNLOADS 下载的标准目录。
DIRECTORY_MOVIES 电影存放的标准目录。
DIRECTORY_MUSIC 音乐存放的标准目录。
DIRECTORY_NOTIFICATIONS 系统通知铃声存放的标准目录。
DIRECTORY_PICTURES 图片存放的标准目录
DIRECTORY_PODCASTS 系统广播存放的标准目录。
DIRECTORY_RINGTONES 系统铃声存放的标准目录。

3获取路径和创建文件,文件夹

1)获取常用的路径,一般开发者这两种路径常用到

//SD卡的路径

SDPATH = Environment.getExternalStorageDirectory().getPath();
//当前程序包的路径
FILESPATH = this.getFilesDir().getPath();
2)创建文件夹,文件
private final static String PATH = "/sdsd/talk/tehst.txt";
private final static String PATH1 = "/sdsd/talk/";
//创建文件夹
File file1 = new File(SDPATH+PATH1);
if (!file1.exists()){
    file1.mkdirs();
}
//创建文件
File file = new File(SDPATH + PATH);
if (!file.exists()) {
    file.createNewFile();
}
3)删除文件

//单个
public boolean deleteSDFile(String fileName) {
    File file = new File(SDPATH  + fileName);
    if (file == null || !file.exists() || file.isDirectory())
        return false;
    return file.delete();
}
//目录下的
public void deleteFile(File file) {
        if (file.exists()) { // 判断文件是否存在
            if (file.isFile()) { // 判断是否是文件
                file.delete(); 
            } else if (file.isDirectory()) { // 否则如果它是一个目录
                File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
                for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
                    this.deleteFile(files[i]); // 把每个文件 用这个方法进行迭代
                }
            }
            file.delete();
        } else {
//            Log.i("文件不存在!"+"\n");
        }
    }
//删除目录下的所有文件及文件夹

public static void delete(File file) {  
        if (file.isFile()) {  
            file.delete();  
            return;  
        }  
        if(file.isDirectory()){  
            File[] childFiles = file.listFiles();  
            if (childFiles == null || childFiles.length == 0) {  
                file.delete();  
                return;  
            }  
      
            for (int i = 0; i < childFiles.length; i++) {  
                delete(childFiles[i]);  
            }  
            file.delete();  
        }  
    } 

4)文件的读写

闲话少说,直接上代码


FileOutputStream写入文件

/**
 * 写入内容到SD卡中的txt文本中
 * str为内容
 */
public void writeSDFile(String str,String fileName) {
    try {
        FileWriter fw = new FileWriter(SDPATH + fileName);
        File f = new File(SDPATH  + fileName);
        fw.write(str);
        FileOutputStream os = new FileOutputStream(f);
        DataOutputStream out = new DataOutputStream(os);
        out.writeShort(2);
        out.writeUTF("");
        System.out.println(out);
        fw.flush();
        fw.close();
        System.out.println(fw);
    } catch (Exception e) {
    }
}
 
 
BufferedWriter写入文件
try {  
    File file = new File(Environment.getExternalStorageDirectory(),  
            DEFAULT_FILENAME);  
    //第二个参数意义是说是否以append方式添加内容  
    BufferedWriter bw = new BufferedWriter(new FileWriter(file, true));  
    String info = " hey, you gey!";  
    bw.write(info);  
    bw.flush();  
    System.out.println("写入成功");  
} catch (Exception e) {  
    e.printStackTrace();  
}  


使用FileInputStream读取文件
/**
 * 读取SD卡中文本文件
 *
 * @param fileName
 * @return
 */
public String readSDFile(String fileName) {
    StringBuffer sb = new StringBuffer();
    File file = new File(SDPATH  + fileName);
    try {
        FileInputStream fis = new FileInputStream(file);
        int c;
        while ((c = fis.read()) != -1) {
            sb.append((char) c);
        }
        fis.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return sb.toString();
}
 
 
使用BufferReader读取文件

public String readFile(String fileName){
    try {
        File file = new File(Environment.getExternalStorageDirectory(),
                fileName);
        BufferedReader br = new BufferedReader(new FileReader(file));
        String readline = "";
        StringBuffer sb = new StringBuffer();
        while ((readline = br.readLine()) != null) {
            System.out.println("readline:" + readline);
            sb.append(readline);
        }
        br.close();
        System.out.println("读取成功:" + sb.toString());
        return sb.toString();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
RandomAccessFile对文件的读写

  1. import java.io.*;    
  2.     
  3. public class RandomAccessFileDemo {    
  4.  public static void main(String[] args) throws Exception {    
  5.   RandomAccessFile file = new RandomAccessFile("file""rw");    
  6.   // 以下向file文件中写数据    
  7.   file.writeInt(20);// 占4个字节    
  8.   file.writeDouble(8.236598);// 占8个字节    
  9.   file.writeUTF("这是一个UTF字符串");// 这个长度写在当前文件指针的前两个字节处,可用readShort()读取    
  10.   file.writeBoolean(true);// 占1个字节    
  11.   file.writeShort(395);// 占2个字节    
  12.   file.writeLong(2325451l);// 占8个字节    
  13.   file.writeUTF("又是一个UTF字符串");    
  14.   file.writeFloat(35.5f);// 占4个字节    
  15.   file.writeChar('a');// 占2个字节    
  16.     
  17.   file.seek(0);// 把文件指针位置设置到文件起始处    
  18.     
  19.   // 以下从file文件中读数据,要注意文件指针的位置    
  20.   System.out.println("——————从file文件指定位置读数据——————");    
  21.   System.out.println(file.readInt());    
  22.   System.out.println(file.readDouble());    
  23.   System.out.println(file.readUTF());    
  24.     
  25.   file.skipBytes(3);// 将文件指针跳过3个字节,本例中即跳过了一个boolean值和short值。    
  26.   System.out.println(file.readLong());    
  27.     
  28.   file.skipBytes(file.readShort()); // 跳过文件中“又是一个UTF字符串”所占字节,注意readShort()方法会移动文件指针,所以不用加2。    
  29.   System.out.println(file.readFloat());    
  30.       
  31.   //以下演示文件复制操作    
  32.   System.out.println("——————文件复制(从file到fileCopy)——————");    
  33.   file.seek(0);    
  34.   RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");    
  35.   int len=(int)file.length();//取得文件长度(字节数)    
  36.   byte[] b=new byte[len];    
  37.   file.readFully(b);    
  38.   fileCopy.write(b);    
  39.   System.out.println("复制完成!");    
  40.  }    

除了对SDcard上的文件进行读写,在很多时候还需要读取项目文件夹下的资源,如raw和asset

从resource的raw中读取文件数据:

  1. String res = "";   
  2. try{   
  3.    
  4.     //得到资源中的Raw数据流  
  5.     InputStream in = getResources().openRawResource(R.raw.test);   
  6.   
  7.     //得到数据的大小  
  8.     int length = in.available();         
  9.   
  10.     byte [] buffer = new byte[length];          
  11.   
  12.     //读取数据  
  13.     in.read(buffer);           
  14.   
  15.     //依test.txt的编码类型选择合适的编码,如果不调整会乱码   
  16.     res = EncodingUtils.getString(buffer, "BIG5");   
  17.       
  18.     //关闭      
  19.     in.close();              
  20.   
  21.    }catch(Exception e){   
  22.       e.printStackTrace();           
  23.    }  
从resource的asset中读取文件数据:

  1. String fileName = "test.txt"//文件名字   
  2. String res="";   
  3. try{   
  4.   
  5.    //得到资源中的asset数据流  
  6.    InputStream in = getResources().getAssets().open(fileName);   
  7.   
  8.    int length = in.available();           
  9.    byte [] buffer = new byte[length];          
  10.   
  11.    in.read(buffer);              
  12.    in.close();  
  13.    res = EncodingUtils.getString(buffer, "UTF-8");       
  14.   
  15.   }catch(Exception e){   
  16.   
  17.       e.printStackTrace();           
  18.   
  19.    }   


获取扩展存储设备的大小
 
   String sdcard = Environment.getExternalStorageDirectory().getPath();
   StatFs statFs = new StatFs(sdcard);
   long blockSize = statFs.getBlockSize();//返回以字节为单位的一个文件系统大小
   long blockCount = statFs.getBlockCount() ;
   long blocks = statFs.getAvailableBlocks();//获取当前可用的存储空间
   long availableSpare = (blocks * blockSize) / (1024 * 1024);

  1. String Name = File.getName();  //获得文件或文件夹的名称:  
  2. String parentPath = File.getParent();  //获得文件或文件夹的父目录  
  3. String path = File.getAbsoultePath();//绝对路经  
  4. String path = File.getPath();//相对路经   
  5. File.createNewFile();//建立文件    
  6. File.mkDir(); //建立文件夹    
  7. File.isDirectory(); //判断是文件或文件夹  
  8. File[] files = File.listFiles();  //列出文件夹下的所有文件和文件夹名  
  9. File.renameTo(dest);  //修改文件夹和文件名  
  10. File.delete();  //删除文件夹或文件 

1、apk中有两种资源文件,使用两种不同的方式进行打开使用。
raw使用InputStream in = getResources().openRawResource(R.raw.test);
asset使用InputStream in = getResources().getAssets().open(fileName);

这些数据只能读取,不能写入。更重要的是该目录下的文件大小不能超过1M。

同时,需要注意的是,在使用InputStream的时候需要在函数名称后加上throws IOException。

2、SD卡中的文件使用FileInputStream和FileOutputStream进行文件的操作。
3、存放在数据区(/data/data/..)的文件只能使用openFileOutput和openFileInput进行操作。
注意不能使用FileInputStream和FileOutputStream进行文件的操作。
4、RandomAccessFile类仅限于文件的操作,不能访问其他IO设备。它可以跳转到文件的任意位置,从当前位置开始读写。

5、InputStream和FileInputStream都可以使用skip和read(buffre,offset,length)函数来实现文件的随机读取。


文件的读写操作基础也就这些了,对于深入复杂的暂不总结,这些知识点也很常见,大路边上的,浮于表面,只是总结一下,闲暇时候可以翻出来看看,希望也能对你有帮助。


特别感谢以下大神的文章:

参考:http://www.2cto.com/kf/201408/327215.html

http://blog.sina.com.cn/s/blog_5da93c8f010110sn.html

http://blog.youkuaiyun.com/mad1989/article/details/37568667

http://www.jb51.net/article/34296.htm

http://blog.youkuaiyun.com/ztp800201/article/details/7322110

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值