第十一章:Android数据存储(上)
一、Android的文件系统
- Android系统文件目录
| 目录 | 内容 | 
| system | 系统目录,放置在Android运行所需的核心库 | 
| data | 应用目录,放置着运行在Android上的应用及其数据 | 
| sdcar | 扩展存储卡目录,用来存放共享的数据 | 
| mnt | 记录Android挂载的外部存储信息 | 
2.Android的应用数据存储机制
在Android中,第三方应用及其数据,都存放在data目录下。其中,应用安装包会被存放到/data/app/目录下,每个安装包的文件名都形如:应用包名.apk,以避免重复。 比如包名为com.test.sample的应用,其应用数据的目录为/data/data/com.test.sample/。对应的数据库文件存储在/data/data/com.test.sample/database/目录下,设置文件存储在/data/data/com.test.sample/shared_prefs/,自定义的应用数据文件存储在目录/data/data/com.test.sample/files/下,等等。 不仅如此,Android还会为每个应用创建一个账号,只有通过本应用的账号才有权限去运行该应用的安装包文件,读写应用数据目录下的文件(当然root权限除外啊~),从而保证了该应用数据不会再被其他应用获取或破坏。
3. Android的文件操作
从应用数据目录下可以看出,数据文件可以分成两类,一类是放置在扩展存储器中的文件,即/sdcard/目录下的文件,它们可以被各个应用共享;而另一类则是放在该应用数据目录下文件,它们仅能被各个应用独享,不能被其他应用读写。 (1)扩展存储器中的文件读写方式跟标准的java文件处理无异。 我们可以新建一个FileUtil的工具类来帮助我们处理文件的I/O操作,首先我们先判断SD卡的状态,看看SD卡是否可用,还有多少可用容量等。新建一个FileUtil的Class,加入方法

1 // =================get SDCard information===================
2 public static boolean isSdcardAvailable() {
3 String status = Environment.getExternalStorageState();
4 //Environment.MEDIA_MOUNTED表示SD卡正常挂载
5 if (status.equals(Environment.MEDIA_MOUNTED)) {
6 return true;
7 }
8 return false;
9 }
10
11 public static long getSDAllSizeKB() {
12 //sd卡的位置
13 File path = Environment.getExternalStorageDirectory();
14 //StatFs获取的都是以block为单位的
15 StatFs sf = new StatFs(path.getPath());
16 // 得到单个block的大小
17 long blockSize = sf.getBlockSize();
18 // 获取所有数据块数
19 long allBlocks = sf.getBlockCount();
20 // 返回SD卡大小
21 return (allBlocks * blockSize) / 1024; // KB
22 }
23
24 /**
25 * free size for normal application
26 * @return
27 */
28 public static long getSDAvalibleSizeKB() {
29 File path = Environment.getExternalStorageDirectory();
30 StatFs sf = new StatFs(path.getPath());
31 long blockSize = sf.getBlockSize();
32 long avaliableSize = sf.getAvailableBlocks();
33 return (avaliableSize * blockSize) / 1024;// KB
34 }

Environment.getExternalStorageDirectory()表示获取扩展存储器的目录。(建议使用此方法动态获取,因为sdcard这个目录路径是可配置的) StatFs.getBlockSize在API18后变为StatFs.getBlockSizeLong,其他类似的getBlock方法也一样,关于StatFs,详情可以看这篇博文 然后在activity中的button1加入事件

case R.id.button1: {
            Log.d("TEST", "sdcard?"+FileUtil.isSdcardAvailable());
            Log.d("TEST", "全部容量"+(float)FileUtil.getSDAllSizeKB()/1024/1024);
            Log.d("TEST", "可用容量"+(float)FileUtil.getSDAvalibleSizeKB()/1024/1024);
            Toast.makeText(this, "status", Toast.LENGTH_SHORT).show();
            break;
        }

运行结果如下 
接下来我们来判断某个文件夹是否存在在SD卡中以及创建一个文件夹

/**
* @param director 文件夹名称
* @return
*/
public static boolean isFileExist(String director) {
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + director);
return file.exists();
} /**
* create multiple director
* @param path
* @return
*/
public static boolean createFile(String director) {
if (isFileExist(director)) {
return true;
} else {
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + director);
if (!file.mkdirs()) {
return false;
}
return true;
}
}

其中File.separator是表示分隔符,在不同操作系统下是不同的,如windows就是代表"/",而在Linux下却是代表"\"。所以介意使用File.separator来代替分隔符。File.mkdirs()表示创建一个文件夹,且可附带创建父目录,而mkdir()不行,详情的File大家可以查看官方文档,或者看看这篇博文 然后在activity中的button2加入响应事件
case R.id.button2: {
            Log.d("TEST", "example文件夹存在?"+FileUtil.isFileExist("example"));
            Log.d("TEST", "创建forexample文件夹"+FileUtil.createFile("forexample"));
            Toast.makeText(this, "IsFile", Toast.LENGTH_SHORT).show();
            break;
        }  
运行后可以看到  我们会发现在手机的sdcard目录下新建了一个forexample的文件夹。 最后我们来实现文件的读和写 写:
 我们会发现在手机的sdcard目录下新建了一个forexample的文件夹。 最后我们来实现文件的读和写 写:

/**
*
* @param director
* (you don't need to begin with
* Environment.getExternalStorageDirectory()+File.separator)
* @param fileName
* @param content
* @param encoding
* (UTF-8...)
* @param isAppend
* : Context.MODE_APPEND
* @return
*/
public static File writeToSDCardFile(String directory, String fileName,
String content, String encoding, boolean isAppend) {
// mobile SD card path +path
File file = null;
OutputStream os = null;
try {
if (!createFile(directory)) {
return file;
}
file = new File(Environment.getExternalStorageDirectory()
+ File.separator + directory + File.separator + fileName);
os = new FileOutputStream(file, isAppend);
if (encoding.equals("")) {
os.write(content.getBytes());
} else {
os.write(content.getBytes(encoding));
}
os.flush();
} catch (IOException e) {
Log.e("FileUtil", "writeToSDCardFile:" + e.getMessage());
} finally {
try {
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
} /**
* write data from inputstream to SDCard
*/
public File writeToSDCardFromInput(String directory, String fileName,
InputStream input) {
File file = null;
OutputStream os = null;
try {
if (createFile(directory)) {
return file;
}
file = new File(Environment.getExternalStorageDirectory()
+ File.separator + directory + File.separator + fileName);
os = new FileOutputStream(file);
byte[] data = new byte[bufferd];
int length = -1;
while ((length = input.read(data)) != -1) {
os.write(data, 0, length);
}
// clear cache
os.flush();
} catch (Exception e) {
Log.e("FileUtil", "" + e.getMessage());
e.printStackTrace();
} finally {
try {
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return file;
}

从上面可以看到有两种写入的方法,一种是将字符串直接写入,另一种是将数据流写到文件中。还有一点要提的是file的默认目录就是sdcard的目录,所以开头不必每次都要加sdcard的目录路径。 FileOutputStream(file, isAppend) 两个参数,左边是File文件,而右边是一个boolean值,为true时,数据将会接在原来文件的后面写入,而false是则会覆盖。 读:

public static String ReadFromSDCardFile(String directory,String fileName){
        String res="";
        File file = null;
        file = new File(Environment.getExternalStorageDirectory()
                + File.separator + directory + File.separator + fileName);
        try {
            FileInputStream fis = new FileInputStream(file);
            int length = fis.available();
            byte [] buffer = new byte[length];
            fis.read(buffer);             //将字节按照编码格式转成字符串
            res = EncodingUtils.getString(buffer, "UTF-8");
            fis.close();
            return res;
        }catch (FileNotFoundException  e) {
            // TODO Auto-generated catch block
            Log.d("TEST", "FileNotFound");
            e.printStackTrace();
        }catch (Exception  e) {
            Log.d("TEST", "Can Not Open File");
            e.printStackTrace();
        }
        return null;
    }

编码默认是UTF-8,若是想要改变的话,将其作为参数传入就行。 Activity中在按钮中加入响应

case R.id.button3: {
            FileUtil.writeToSDCardFile("forexample", "test.txt",
                    editText.getText().toString(), "UTF-8", true);
            Toast.makeText(this, "WriteFile", Toast.LENGTH_SHORT).show();
            break;
        }
        case R.id.button4: {
            textView.setText(FileUtil.ReadFromSDCardFile("forexample", "test.txt"));
            Toast.makeText(this, "ReadFile", Toast.LENGTH_SHORT).show();
            break;
        }

在文字编辑框上写入“我是cpacm”,先点击writefile按钮,再点击ReadFile,得到运行结果

同时在根目录下的forexample文件夹里会找到test.txt,里面有着“我是cpacm”的一行字。到此,文件的读写成功。 (2)放在该应用数据目录下的文件读写 存储在应用目录下的私有数据目录,通常不会通过File类的方式直接读写,而是利用一些封装过的类或函数来操作。一般可以通过Context.openFileOutput来执行。 在Activity加入两个方法,分别为文件的读和写

    public void writeFile(String fileName,String writestr){
        try{
                FileOutputStream fout =openFileOutput(fileName,MODE_PRIVATE);
                byte [] bytes = writestr.getBytes();
                fout.write(bytes);
                fout.close();
              }
                catch(Exception e){
                e.printStackTrace();
               }
        } 
        //读数据
    public String readFile(String fileName){
      String res="";
      try{
             FileInputStream fin = openFileInput(fileName);
             int length = fin.available();
             byte [] buffer = new byte[length];
             fin.read(buffer);
             res = EncodingUtils.getString(buffer, "UTF-8");
             fin.close();
         }
         catch(Exception e){
             e.printStackTrace();
         }
         return res;
    }

同时在按钮的响应中加入

case R.id.button5: {
            writeFile("test2.txt",editText.getText().toString());
            Toast.makeText(this, "WritePrivateFile", Toast.LENGTH_SHORT).show();
            break;
        }
        case R.id.button6: {
            textView.setText(readFile("test2.txt"));
            Toast.makeText(this, "ReadPrivateFile", Toast.LENGTH_SHORT).show();
            break;
        }

效果图跟上张一样。
最后不要忘记在配置文件中声明权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
二、Android设置文件的使用
用户在使用应用时,常常会有一些个人偏好。为了满足不同用户的需求,应用通常会提供对应的设置项(Preference),让用户根据自己的喜好选择。这些设置信息会存储在本地并进行结构化地展示,使用户可以编辑。
- 设置文件的存储和使用
 Android应用的设置数据,可以通过android.content.SharedPreferences类来表示。它提供了一组数据读取的接口,可以从设置文件中读取给定键值的整形数,布尔型数等数据。 首先是获取SharedPreferencesprivate SharedPreferences userInfo;  //在界面组件或服务组件中调用,构造应用默认的设置文件,默认文件名字为_preferences.xml 
 //userInfo = PreferenceManager.getDefaultSharedPreferences(this);
 //或获取指定名字的SharedPreferences对象 参数分别为存储的文件名和存储模式。
 userInfo = getSharedPreferences("preferences", Activity.MODE_PRIVATE); //读取数据,如果无法找到则会使用默认值
 String username = userInfo.getString("name", "未定义姓名");
 String msg = userInfo.getString("msg", "未定义信息");
 //显示文本
 textView.setText(username+","+msg); 两种获取方式,默认或者指定一个文件 接下来加入响应按钮  case R.id.button7: {
 //获得SharedPreferences的编辑器
 SharedPreferences.Editor editor = userInfo.edit();
 //将信息存入相应的键值中
 editor.putString("name", editText.getText().toString()).commit();
 Toast.makeText(this, "SetName", Toast.LENGTH_SHORT).show();
 break;
 }
 case R.id.button8: {
 //获得SharedPreferences的编辑器
 SharedPreferences.Editor editor = userInfo.edit();
 //将信息存入相应的键值中ss
 editor.putString("msg", editText.getText().toString()).commit();
 Toast.makeText(this, "SetMessage", Toast.LENGTH_SHORT).show();
 break;
 }
 case R.id.button9: { //获得SharedPreferences文件
 userInfo = getSharedPreferences("preferences", Activity.MODE_PRIVATE);
 String username = userInfo.getString("name", "未定义姓名");
 String msg = userInfo.getString("msg", "未定义信息");
 textView.setText(username+","+msg);
 Toast.makeText(this, "ShowMsg", Toast.LENGTH_SHORT).show();
 break;
 }
 case R.id.button10: { //输出XML文件
 textView.setText(print());
 Toast.makeText(this, "ShowXML", Toast.LENGTH_SHORT).show();
 break;
 } 按钮7,8可以设置信息,按钮9则从SharedPreferences文件中读取信息并显示在文字框中。按钮10会显示这个XML文件中的所有信息。  
 访问其他应用中的Preference(在SecondApp中访问FirstApp的数据),前提条件是:FirstApp的preference创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE权限。如:在<package name>为com.first.app的应用使用下面语句创建了preference("first_app_perferences")。 Java代码getSharedPreferences("first_app_perferences", Context.MODE_WORLD_READABLE); 在SecondApp中要访问FirstApp应用中的preference,首先需要创建FirstApp应用的Context,然后通过Context 访问preference ,访问preference时会在应用所在包下的shared_prefs目录找到preference Context firstAppContext = createPackageContext("com.first.app", Context.CONTEXT_IGNORE_SECURITY);
 SharedPreferences sharedPreferences = firstAppContext.getSharedPreferences("first_app_perferences", Context.MODE_WORLD_READABLE);
 String name = sharedPreferences.getString("name", "");
 int age = sharedPreferences.getInt("age", 0);如果不通过创建Context访问FirstApp应用的preference,可以以读取xml文件方式直接访问FirstApp应用的preference对应的xml文件, 如: File xmlFile = new File(“/data/data/<package name>/shared_prefs/first_app_perferences.xml”);//<package name>应替换成应用的包名: com.first.app 
- 设置界面组件 有一类特殊的Preference对象:android.preference.PreferenceGroup。它是容器型的Preference对象,负责管理一组相关联的Preference对象。设置项编辑的界面组件,通常派生自android.preference.PreferenceActivity类。它可以将一个定制好的设置树转换成对应的控件呈现出来。
 public class PreferencesDemo extends PreferenceActivity{
 @Override
 public void onCreate(Bundle savadInstanceState){
 super.onCreate(savadInstanceState);
 this.addPreferencesFromResource(R.xml.preference);
 }
 } 其中,R.xml.preference表示描述设置信息的资源文件。放在XML资源目录下。 详细可以参考Android的配置界面PreferenceActivity 

  1 public class MainActivity extends Activity implements OnClickListener {
  2
  3      /** 存储后的文件路径:/data/data/<package name>/shares_prefs + 文件名.xml */
  4     public static final String PATH = "/data/data/com.example.datademo/shared_prefs/preferences.xml";
  5     private SharedPreferences userInfo;
  6
  7     private Button button1;
  8     private Button button2;
  9     private Button button3;
 10     private Button button4;
 11     private Button button5;
 12     private Button button6;
 13     private Button button7;
 14     private Button button8;
 15     private Button button9;
 16     private Button button10;
 17     private TextView textView;
 18     private EditText editText;
 19
 20     @Override
 21     protected void onCreate(Bundle savedInstanceState) {
 22         super.onCreate(savedInstanceState);
 23         setContentView(R.layout.activity_main);
 24
 25         // 获得界面的控件
 26         textView = (TextView) findViewById(R.id.textView1);
 27         editText = (EditText) findViewById(R.id.editText1);
 28         button1 = (Button) findViewById(R.id.button1);
 29         button1.setOnClickListener(this);
 30         button2 = (Button) findViewById(R.id.button2);
 31         button2.setOnClickListener(this);
 32         button3 = (Button) findViewById(R.id.button3);
 33         button3.setOnClickListener(this);
 34         button4 = (Button) findViewById(R.id.button4);
 35         button4.setOnClickListener(this);
 36         button5 = (Button) findViewById(R.id.button5);
 37         button5.setOnClickListener(this);
 38         button6 = (Button) findViewById(R.id.button6);
 39         button6.setOnClickListener(this);
 40         button7 = (Button) findViewById(R.id.button7);
 41         button7.setOnClickListener(this);
 42         button8 = (Button) findViewById(R.id.button8);
 43         button8.setOnClickListener(this);
 44         button9 = (Button) findViewById(R.id.button9);
 45         button9.setOnClickListener(this);
 46         button10 = (Button) findViewById(R.id.button10);
 47         button10.setOnClickListener(this);
 48
 49         //在界面组件或服务组件中调用,构造应用默认的设置文件,默认文件名字为_preferences.xml
 50         //userInfo = PreferenceManager.getDefaultSharedPreferences(this);
 51         //或获取指定名字的SharedPreferences对象  参数分别为存储的文件名和存储模式。
 52         userInfo = getSharedPreferences("preferences.xml", Activity.MODE_PRIVATE);
 53
 54         //读取数据,如果无法找到则会使用默认值
 55         String username = userInfo.getString("name", "未定义姓名");
 56         String msg = userInfo.getString("msg", "未定义信息");
 57         //显示文本
 58         textView.setText(username+","+msg);
 59     }
 60
 61     @Override
 62     public void onClick(View v) {
 63         // TODO Auto-generated method stub
 64         switch (v.getId()) {
 65         case R.id.button1: {
 66             Log.d("TEST", "sdcard?"+FileUtil.isSdcardAvailable());
 67             Log.d("TEST", "全部容量"+(float)FileUtil.getSDAllSizeKB()/1024/1024);
 68             Log.d("TEST", "可用容量"+(float)FileUtil.getSDAvalibleSizeKB()/1024/1024);
 69             Toast.makeText(this, "status", Toast.LENGTH_SHORT).show();
 70             break;
 71         }
 72         case R.id.button2: {
 73             Log.d("TEST", "example文件夹存在?"+FileUtil.isFileExist("example"));
 74             Log.d("TEST", "创建forexample文件夹"+FileUtil.createFile("forexample"));
 75             Toast.makeText(this, "IsFile", Toast.LENGTH_SHORT).show();
 76             break;
 77         }
 78         case R.id.button3: {
 79             FileUtil.writeToSDCardFile("forexample", "test.txt",
 80                     editText.getText().toString(), "UTF-8", true);
 81             Toast.makeText(this, "WriteFile", Toast.LENGTH_SHORT).show();
 82             break;
 83         }
 84         case R.id.button4: {
 85             textView.setText(FileUtil.ReadFromSDCardFile("forexample", "test.txt"));
 86             Toast.makeText(this, "ReadFile", Toast.LENGTH_SHORT).show();
 87             break;
 88         }
 89         case R.id.button5: {
 90             writeFile("test2.txt",editText.getText().toString());
 91             Toast.makeText(this, "WritePrivateFile", Toast.LENGTH_SHORT).show();
 92             break;
 93         }
 94         case R.id.button6: {
 95             textView.setText(readFile("test2.txt"));
 96             Toast.makeText(this, "ReadPrivateFile", Toast.LENGTH_SHORT).show();
 97             break;
 98         }
 99         case R.id.button7: {
100             //获得SharedPreferences的编辑器
101             SharedPreferences.Editor editor = userInfo.edit();
102             //将信息存入相应的键值中
103             editor.putString("name", editText.getText().toString()).commit();
104             Toast.makeText(this, "SetName", Toast.LENGTH_SHORT).show();
105             break;
106         }
107         case R.id.button8: {
108             //获得SharedPreferences的编辑器
109             SharedPreferences.Editor editor = userInfo.edit();
110             //将信息存入相应的键值中ss
111             editor.putString("msg", editText.getText().toString()).commit();
112             Toast.makeText(this, "SetMessage", Toast.LENGTH_SHORT).show();
113             break;
114         }
115         case R.id.button9: {
116             userInfo = getSharedPreferences("preferences.xml", Activity.MODE_PRIVATE);
117             String username = userInfo.getString("name", "未定义姓名");
118             String msg = userInfo.getString("msg", "未定义信息");
119             textView.setText(username+","+msg);
120             Toast.makeText(this, "ShowMsg", Toast.LENGTH_SHORT).show();
121             break;
122         }
123         case R.id.button10: {
124             textView.setText(print());
125             Toast.makeText(this, "ShowXML", Toast.LENGTH_SHORT).show();
126             break;
127         }
128         }
129     }
130
131     public void writeFile(String fileName,String writestr){
132         try{
133                 FileOutputStream fout =openFileOutput(fileName,MODE_PRIVATE);
134                 byte [] bytes = writestr.getBytes();
135                 fout.write(bytes);
136                 fout.close();
137               }
138                 catch(Exception e){
139                 e.printStackTrace();
140                }
141         }
142
143         //读数据
144     public String readFile(String fileName){
145       String res="";
146       try{
147              FileInputStream fin = openFileInput(fileName);
148              int length = fin.available();
149              byte [] buffer = new byte[length];
150              fin.read(buffer);
151              res = EncodingUtils.getString(buffer, "UTF-8");
152              fin.close();
153          }
154          catch(Exception e){
155              e.printStackTrace();
156          }
157          return res;
158     }
159
160     private String print() {
161         StringBuffer buff = new StringBuffer();
162         try {
163             BufferedReader reader = new BufferedReader(new InputStreamReader(
164                     new FileInputStream(PATH)));
165             String str;
166             while ((str = reader.readLine()) != null) {
167                 buff.append(str + "/n");
168             }
169         } catch (Exception e) {
170             e.printStackTrace();
171         }
172         return buff.toString();
173     }
174
175 }


1 package com.example.datademo;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.OutputStream;
10
11 import org.apache.http.util.EncodingUtils;
12
13 import android.os.Environment;
14 import android.os.StatFs;
15 import android.util.Log;
16
17 public class FileUtil {
18 private static int bufferd = 1024;
19
20 private FileUtil() {
21 }
22
23 /*
24 * <!-- 在SDCard中创建与删除文件权限 --> <uses-permission
25 * android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!--
26 * 往SDCard写入数据权限 --> <uses-permission
27 * android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
28 */
29
30 // =================get SDCard information===================
31 public static boolean isSdcardAvailable() {
32 String status = Environment.getExternalStorageState();
33 //Environment.MEDIA_MOUNTED表示SD卡正常挂载
34 //sd卡 http://blog.csdn.net/yuzhiboyi/article/details/8645730
35 if (status.equals(Environment.MEDIA_MOUNTED)) {
36 return true;
37 }
38 return false;
39 }
40
41 public static long getSDAllSizeKB() {
42 // get path of sdcard
43 File path = Environment.getExternalStorageDirectory();
44 //StatFs获取的都是以block为单位的 http://blog.csdn.net/pang3510726681/article/details/6969557
45 StatFs sf = new StatFs(path.getPath());
46 // get single block size(Byte)
47 long blockSize = sf.getBlockSize();
48 // 获取所有数据块数
49 long allBlocks = sf.getBlockCount();
50 // 返回SD卡大小
51 return (allBlocks * blockSize) / 1024; // KB
52 }
53
54 /**
55 * free size for normal application
56 *
57 * @return
58 */
59 public static long getSDAvalibleSizeKB() {
60 File path = Environment.getExternalStorageDirectory();
61 StatFs sf = new StatFs(path.getPath());
62 long blockSize = sf.getBlockSize();
63 long avaliableSize = sf.getAvailableBlocks();
64 return (avaliableSize * blockSize) / 1024;// KB
65 }
66
67 // =====================File Operation==========================
68 /**
69 * @param director 文件夹名称
70 * @return
71 */
72 public static boolean isFileExist(String director) {
73 File file = new File(Environment.getExternalStorageDirectory()
74 + File.separator + director);
75 return file.exists();
76 }
77
78 /**
79 * create multiple director
80 *
81 * @param path
82 * @return
83 */
84 public static boolean createFile(String director) {
85 if (isFileExist(director)) {
86 return true;
87 } else {
88 File file = new File(Environment.getExternalStorageDirectory()
89 + File.separator + director);
90 if (!file.mkdirs()) {
91 return false;
92 }
93 return true;
94 }
95 }
96
97 public static File writeToSDCardFile(String directory, String fileName,
98 String content, boolean isAppend) {
99 return writeToSDCardFile(directory, fileName, content, "", isAppend);
100 }
101
102 /**
103 *
104 * @param director
105 * (you don't need to begin with
106 * Environment.getExternalStorageDirectory()+File.separator)
107 * @param fileName
108 * @param content
109 * @param encoding
110 * (UTF-8...)
111 * @param isAppend
112 * : Context.MODE_APPEND
113 * @return
114 */
115 public static File writeToSDCardFile(String directory, String fileName,
116 String content, String encoding, boolean isAppend) {
117 // mobile SD card path +path
118 File file = null;
119 OutputStream os = null;
120 try {
121 if (!createFile(directory)) {
122 return file;
123 }
124 file = new File(Environment.getExternalStorageDirectory()
125 + File.separator + directory + File.separator + fileName);
126 os = new FileOutputStream(file, isAppend);
127 if (encoding.equals("")) {
128 os.write(content.getBytes());
129 } else {
130 os.write(content.getBytes(encoding));
131 }
132 os.flush();
133 } catch (IOException e) {
134 Log.e("FileUtil", "writeToSDCardFile:" + e.getMessage());
135 } finally {
136 try {
137 if (os != null) {
138 os.close();
139 }
140 } catch (IOException e) {
141 e.printStackTrace();
142 }
143 }
144 return file;
145 }
146
147 /**
148 * write data from inputstream to SDCard
149 */
150 public static File writeToSDCardFromInput(String directory, String fileName,
151 InputStream input) {
152 File file = null;
153 OutputStream os = null;
154 try {
155 if (createFile(directory)) {
156 return file;
157 }
158 file = new File(Environment.getExternalStorageDirectory()
159 + File.separator + directory + File.separator + fileName);
160 os = new FileOutputStream(file);
161 byte[] data = new byte[bufferd];
162 int length = -1;
163 while ((length = input.read(data)) != -1) {
164 os.write(data, 0, length);
165 }
166 // clear cache
167 os.flush();
168 } catch (Exception e) {
169 Log.e("FileUtil", "" + e.getMessage());
170 e.printStackTrace();
171 } finally {
172 try {
173 os.close();
174 } catch (Exception e) {
175 e.printStackTrace();
176 }
177 }
178 return file;
179 }
180
181 public static String ReadFromSDCardFile(String directory,String fileName){
182 String res="";
183 File file = null;
184 file = new File(Environment.getExternalStorageDirectory()
185 + File.separator + directory + File.separator + fileName);
186 try {
187 FileInputStream fis = new FileInputStream(file);
188 int length = fis.available();
189 byte [] buffer = new byte[length];
190 fis.read(buffer);
191 res = EncodingUtils.getString(buffer, "UTF-8");
192 fis.close();
193 return res;
194 }catch (FileNotFoundException e) {
195 // TODO Auto-generated catch block
196 Log.d("TEST", "FileNotFound");
197 e.printStackTrace();
198 }catch (Exception e) {
199 Log.d("TEST", "Can Not Open File");
200 e.printStackTrace();
201 }
202 return null;
203 }
204 }
第十一章:Android数据存储(上)的更多相关文章
- 第8章 Android数据存储与IO——File存储
		openFileOutput/openFileInput 这是android自带的两种解决方案. 
- 【Android开发日记】之入门篇(七)——Android数据存储(上)
		在讲解Android的数据源组件——ContentProvider之前我觉得很有必要先弄清楚Android的数据结构. 数据和程序是应用构成的两个核心要素,数据存储永远是应用开发中最重要的主题之一,也 ... 
- Android数据存储-通过SharedPreferences实现记住密码的操作
		在Android中登陆中,为了实现用户的方便,往往需要根据用户的需要进行记住密码的操作,所以,在Android数据存储中SharedPreferences恰恰可以实现这一点 下面,小编将带领大家通过S ... 
- Android - 数据存储 -存储文件
		Android使用的文件系统和其他平台的基本磁盘的文件系统很相似.这里将要介绍如何使用File API在Android文件系统中读写文件. File对象适合按顺序读写大量的数据.例如,适合图片文件或者 ... 
- Android - 数据存储 -存储键值对
		如果你有少量的键值数据需要存储,可以使用SharedPreferencesAPI.SharedPreferences对象指向一个包含键值对的文件并且提供了一些简单的方法来读取它们.每个SharedPr ... 
- Android数据存储:SDCard
		Android数据存储之SDCard 0.获取sd卡路径. 1.讲述 Environment 类. 2.讲述 StatFs 类. 3.完整例子读取 SDCard 内存 0.获取sd卡路径 方法一: p ... 
- Android数据存储:Shared Preferences
		Android数据存储之SharedPreferences 在Android系统中提供了多种存储技术.通过这些存储技术可以将数据存储在各种存储介质上, Android 为数据存储提供了如下几种方式:1 ... 
- Android 数据存储01之SharedPreferences
		Android 数据存储01之SharedPreferences 版本 修改内容 日期 修改人 V1.0 原始版本 2013/2/20 skywang 1 SharedPreferences概括 Sh ... 
- 【Android开发日记】之入门篇(八)——Android数据存储(下)
		废话不多说了,紧接着来讲数据库的操作吧.Come On! 提到数据存储问题,数据库是不得不提的.数据库是用来存储关系型数据的不二利器.Android为开发者提供了强大的数据库支持,可以用来轻松地构造基 ... 
- Android数据存储之SQLite数据库
		Android数据存储 之SQLite数据库简介 SQLite的相关知识,并结合Java实现对SQLite数据库的操作. SQLite是D.Richard Hipp用C语言编写的开源嵌入式数据库引擎. ... 
随机推荐
- C++连接mysql的两种方式(ADO连接和mysql api连接)
			一.ADO连接mysql 1.安装mysql-5.5.20-win32.msi和mysql-connector-odbc-5.3.4-win32.msi(一般两个安装程序要匹配,否则可能连接不上) ... 
- 一个很酷的加载loading效果--IT蓝豹
			一个很酷的加载loading效果,自定义LeafLoadingView实现,LeafLoadingView继承view, 本例子主要由以下几点构成 (1):RotateAnimation实现叶子旋转 ... 
- .net该的帐
			1.web api 2.socket通信 3.NUnit单元测试 4.了解自动化测试各种工具 
- rutime中动态调用类的方法
			Dynamically invoke a class method in Objective C 代码 #import <Foundation/Foundation.h> #import ... 
- hdu 1577 WisKey的眼神 (数学几何)
			WisKey的眼神 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ... 
- HDOJ 4508 湫湫系列故事——减肥记I (完全背包带优化)
			完全背包的模版题.. 加了一个小优化 n^2的写法 O(V+N)在本题中复杂度较高 不采纳 完全背包问题有一个很简单有效的优化,是这样的:若两件物品i.j满足c[i]<=c[j]且w[i]&g ... 
- DUILIB 背景贴图
			贴图的描述 方式有两种 // 1.aaa.jpg // 2.file='aaa.jpg' res='' restype='0' dest='0,0,0,0' source='0,0,0,0 ... 
- IOS网络编程。。
			ASI 与AFN框架: 越低层性能越好. AFNetworking ASIHTTPRequest(性能好点) NSURL会更好. NSURL NSURLRequest NSData * data = ... 
- POJ 3686 The Windy's 最小费用最大流
			每个工厂拆成N个工厂,费用分别为1~N倍原费用. //#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ... 
- php protected封装
			<?//父类class father{ public function a(){ echo 'father->a()'.'<br>'; echo "func ... 
