Android文件读写
版本 |
修改内容 |
日期 |
修改人 |
V1.0 |
原始版本 |
2013/2/25 |
skywang |
|
|
|
|
Android文件读写的有两种方式。一种,是通过标准的JavaIO库去读写。另一种,是通过Context提供的接口去读写。
两种方式的原理是一样的,只是API接口不同。下面分别对两种方式进行介绍。
1 通过Java IO库读写文件
当我们想读写公用的目录,如图片、提示音;或者读写外部扩展卡上的文件时,一般都选择通过Java IO库去读写。当通过Java IO库去读写文件时,一般会用到Android Enviroment的接口(如读取外部sdcard的路径、状态等)。
1.1 Android Enviroment
下面分别对Android Eviroment涉及到的函数和变量进行说明
表01_ Enviroment API接口
Enviroment API接口 |
|
API名称 |
说明 |
staticFile getDataDirectory() |
获取Android的数据目录。 |
staticFile getDownloadCacheDirectory() |
获取的Android下载/缓存内容的目录。 |
staticFile getExternalStorageDirectory() |
获取Android的外部存储目录(即sdcard目录)。 |
staticFile getExternalStoragePublicDirectory(String type) |
获取为特定类型的文件放在顶层的公共外部存储目录。 |
staticString getExternalStorageState() |
获取的主要外部存储设备的当前状态(即sdcard目录的状态)。 |
staticFile getRootDirectory() |
获取Android的根目录。 |
返回设备是否有外部存储设备的仿真。 |
|
返回主“外部存储设备是否是可拆卸的。 |
表02_Enviroment sdcard卡状态说明
Enviroment 公用目录参数 |
||
类型 |
名称 |
说明 |
标准的铃声目录 |
||
相机拍照或录像文件的存储目录 |
||
下载目录 |
||
电影目录 |
||
音乐目录 |
||
提示音目录 |
||
图片目录 |
||
播客目录 |
||
铃声目录 |
表03_ Enviroment sdcard卡状态说明
Enviroment sdcard卡状态说明 |
|
状态名称 |
说明 |
非法移除状态:移除sdcard之前,没有卸载sdcard。 |
|
检查状态:检查sdcard的有效性 |
|
挂载状态:sdcard卡已经成功挂载。 |
|
只读状态:sdcard已经挂载,但是是只读的。 |
|
NOFS状态:识别到sdcard卡,但无法挂载。无法挂载原因,可能是sdcard无存储介质,或者sdcard卡的文件系统与android无兼容。 |
|
移除状态:sdcard成功移除。 |
|
共享状态:识别到sdcard卡,但sdcard未挂载,而是作为mass storage等设备(如以u盘的方式连接到电脑上)。 |
|
无法挂载状态:识别到sdcard卡,但无法挂载。无法挂载的原因,可能是sdcard的存储介质部分损坏。 |
|
未挂载:识别到sdcard,但没有挂载。 |
1.2 Android Enviroment实例
AndroidManifest.xml
<?xml version="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.yarin.Android.HelloAndroid" android:versionCode="1" android:versionName="1.0"> <!-- 往SDCard写入数据权限 --> <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:icon="@drawable/icon"android:label="@string/app_name"> <activity android:name=".HelloAndroid" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN" /> <categoryandroid:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="5" /> </manifest>
HelloAndroid.java
package com.yarin.Android.HelloAndroid; import android.app.Activity; import android.os.Bundle; import android.util.Log; import java.io.*; import android.os.Environment; // 测试Enviroment环境变量 public class HelloAndroid extends Activity { private static final String TAG = "skywang-->HelloAndroid"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); isSdcardMounted() ; publicDirTest() ; enviromentAPITest() ; } private boolean isSdcardMounted() { String str = Environment.getExternalStorageState(); boolean ret = Environment.MEDIA_MOUNTED.equals(str); Log.d(TAG, "isSdcardMounted ret="+ret); return ret; } private void enviromentAPITest() { Log.d(TAG, "isExternalStorageEmulated="+Environment.isExternalStorageEmulated()); Log.d(TAG, "isExternalStorageRemovable="+Environment.isExternalStorageRemovable()); File file = null; file = Environment.getDataDirectory(); Log.d(TAG, "getDataDirectory()="+file.getPath()); file = Environment.getExternalStorageDirectory(); Log.d(TAG, "getExternalStorageDirectory()="+file.getPath()); file = Environment.getDownloadCacheDirectory(); Log.d(TAG, "getDownloadCacheDirectory()="+file.getPath()); file = Environment.getRootDirectory(); Log.d(TAG, "getRootDirectory()="+file.getPath()); } private void publicDirTest() { File file = null; file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_NOTIFICATIONS); Log.d(TAG, "DIRECTORY_NOTIFICATIONS="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS); Log.d(TAG, "DIRECTORY_ALARMS="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); Log.d(TAG, "DIRECTORY_DCIM="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); Log.d(TAG, "DIRECTORY_DOWNLOADS="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); Log.d(TAG, "DIRECTORY_MOVIES="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); Log.d(TAG, "DIRECTORY_MUSIC="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); Log.d(TAG, "DIRECTORY_PICTURES="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PODCASTS); Log.d(TAG, "DIRECTORY_PODCASTS="+file.getPath()); file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES); Log.d(TAG, "DIRECTORY_RINGTONES="+file.getPath()); } }
打印结果如下:
D/skywang-->HelloAndroid( 3076):isSdcardMounted ret=true
D/skywang-->HelloAndroid( 3076):DIRECTORY_NOTIFICATIONS=/mnt/sdcard/Notifications
D/skywang-->HelloAndroid( 3076):DIRECTORY_ALARMS=/mnt/sdcard/Alarms
D/skywang-->HelloAndroid( 3076):DIRECTORY_DCIM=/mnt/sdcard/DCIM
D/skywang-->HelloAndroid( 3076):DIRECTORY_DOWNLOADS=/mnt/sdcard/Download
D/skywang-->HelloAndroid( 3076):DIRECTORY_MOVIES=/mnt/sdcard/Movies
D/skywang-->HelloAndroid( 3076):DIRECTORY_MUSIC=/mnt/sdcard/Music
D/skywang-->HelloAndroid( 3076):DIRECTORY_PICTURES=/mnt/sdcard/Pictures
D/skywang-->HelloAndroid( 3076):DIRECTORY_PODCASTS=/mnt/sdcard/Podcasts
D/skywang-->HelloAndroid( 3076):DIRECTORY_RINGTONES=/mnt/sdcard/Ringtones
D/skywang-->HelloAndroid( 3076):isExternalStorageEmulated=false
D/skywang-->HelloAndroid( 3076):isExternalStorageRemovable=false
D/skywang-->HelloAndroid( 3076):getDataDirectory()=/data
D/skywang-->HelloAndroid( 3076):getExternalStorageDirectory()=/mnt/sdcard
D/skywang-->HelloAndroid( 3076):getDownloadCacheDirectory()=/cache
D/skywang-->HelloAndroid( 3076):getRootDirectory()=/system
1.3 Java IO库读写实例
AndroidManifest.xml
<?xml version="1.0"encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yarin.Android.HelloAndroid" android:versionCode="1" android:versionName="1.0"> <!-- 往SDCard写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <application android:icon="@drawable/icon"android:label="@string/app_name"> <activity android:name=".HelloAndroid" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN" /> <categoryandroid:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="5" /> </manifest>
HelloAndroid.java
package com.yarin.Android.HelloAndroid; import android.app.Activity; import android.os.Bundle; import android.util.Log; import java.io.*; import android.os.Environment; // 通过Java IO去读写文件 public class HelloAndroid extends Activity{ privatestatic final String TAG = "skywang-->HelloAndroid"; privateFile sdcardDir = Environment.getExternalStorageDirectory(); privatestatic final String TEST_FILE_NAME = "file.txt"; @Override publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); originalJavaIOWriteTest(); originalJavaIOReadTest(); } privateboolean isSdcardMounted() { returnEnvironment.MEDIA_MOUNTED.equals( Environment.getExternalStorageState()); } privatevoid originalJavaIOReadTest() { if(!isSdcardMounted()) return; try { Filefile = new File(sdcardDir, TEST_FILE_NAME); FileInputStream in = new FileInputStream(file); byte[] bb = new byte[64]; intlen=0; while ((len=in.read(bb))!=-1) { Log.d(TAG, "bb="+newString(bb, 0, len)); } in.close(); } catch (IOException e) { e.printStackTrace(); } } private void originalJavaIOWriteTest() { if(!isSdcardMounted()) return; try { Filefile = new File(sdcardDir, TEST_FILE_NAME); FileOutputStream out = new FileOutputStream(file); String str = "i am skywang!"; byte[] bb = str.getBytes(); for (int i=0; i<bb.length; i++) out.write(bb[i]); out.close(); } catch (IOException e) { e.printStackTrace(); } } }
打印结果如下:
D/skywang-->HelloAndroid( 3298): bb=i am skywang!
2 通过Context提供的接口去读写
Android的Context提供了API用来读写该Activity的私有文件;默认路径是:/data/data/<包>/files/***.***
Context提供了openFileInput()、openFileOutput()、deleteFile()等操作文件。下面简要进行说明
2.1 Context接口说明
public abstract FileInputStream openFileInput (String name)
作 用:打开Activity的私有文件,用于读数据。
参数说明:
name —— 文件名
public abstract FileOutputStream openFileOutput (String name,int mode)
作 用:打开Activity的私有文件,用于写数据。
参数说明:
name —— 文件名
mode —— 写文件的方式,有一下几种值可以选择。
MODE_APPEND:将内容以追加的方式写到文件末尾。
MODE_PRIVATE:默认的方式,创建的文件只能被本Activity所访问。
MODE_WORLD_READABLE:Android API LEVEL 17以后不建议使用。
MODE_WORLD_WRITEABLE:Android API LEVEL 17以后不建议使用。
public abstract String[] fileList ()
作 用:返回Activity私有的文件名组成的列表。
参数说明:无
public abstract boolean deleteFile (String name)
作 用:删除Activity私有的文件。
参数说明:name —— 文件名
2.2 Context实例
HelloAndroid.java
package com.yarin.Android.HelloAndroid; import android.app.Activity; import android.os.Bundle; import android.util.Log; import java.io.*; import android.os.Environment; public class HelloAndroid extends Activity{ privatestatic final String TAG = "skywang-->HelloAndroid"; privatestatic final String TEST_FILE_NAME = "file.txt"; @Override publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //读写测试 activityFileWriteTest(); activityFileReadTest(); //列出当前文件 listActivityFiles(); //删除后再列举 Log.d(TAG,"deleteFile "+TEST_FILE_NAME); deleteFile(TEST_FILE_NAME); listActivityFiles(); } //fileList接口测试 privatevoid listActivityFiles() { String[]arrStr = fileList(); for(int i=0; i<arrStr.length; i++) Log.d(TAG,"index="+i+", file_name ="+arrStr[i]); } //openFileInput接口测试 privatevoid activityFileReadTest() { try { FileInputStream in = openFileInput(TEST_FILE_NAME); byte[] bb = new byte[64]; int len = in.read(bb); Log.d(TAG,"bb="+new String(bb, 0, len)); in.close(); } catch (FileNotFoundException e) { Log.d(TAG,"read file "+TEST_FILE_NAME+" not exist!"); } catch (IOException e){ e.printStackTrace(); } } //openFileOutput接口测试 privatevoid activityFileWriteTest() { try { FileOutputStream out =openFileOutput(TEST_FILE_NAME,MODE_WORLD_READABLE); Stringstr = "this is a activity file test."; out.write(str.getBytes()); out.close(); } catch (FileNotFoundException e) { Log.d(TAG,"write file "+TEST_FILE_NAME+" not exist!"); } catch (IOException e){ e.printStackTrace(); } } }
打印结果如下:
D/skywang-->HelloAndroid( 3414): bb=thisis a activity file test.
D/skywang-->HelloAndroid( 3414):index=0, file_name =file.txt
D/skywang-->HelloAndroid( 3414):deleteFile file.txt
文件保存路径为:/data/data/com.yarin.Android.HelloAndroid/files/file.txt
说明:不同的实例,保存路径可能不一样!
参考文件:
1,Android API文档
2,Java API文档
3,Android实现数据存储技术:http://www.cnblogs.com/hanyonglu/archive/2012/03/01/2374894.html