您的位置:首页 > 移动开发 > Android开发

Android开发--数据存储之File文件存储

2015-01-10 16:39 369 查看
转载来自:http://blog.csdn.net/ahuier/article/details/10364757,并进行扩充
引言:Android开发中的数据存储方式
Android提供了5种方式存储数据:
1. 文件存储数据 [也就是通常说的SD卡中] 
2. 使用SharedPreferences存储数据 (共享参数) 
3. SQLite数据库存储数据  
4. 使用ContentProvider存储数据  (内容提供器)
5. 网络存储数据 [可以把本地的数据存储在网络的服务端]
一:文件存储简介
Java提供了一套完整的IO流体系,包括FileInputStream和FileOutputStream等,通过这些类我们可以方便的访问磁盘上的文件内容,Android同样支持这种方式访问手机存储器上的文件。
Android上下文提供了如下两个方法来打开应用程序的数据文件夹里的文件IO流:
1)FileInputStream openFileInput(String name):打开应用程序的数据文件夹下的name文件对应的输入流

2) FileOutStream openFileOutput(Stringname,int mode):打开应用程序的数据文件夹下的name文件对应输出流
mode : 指定打开文件的模式,该模式支持如下值
Context.MODE_PRIVATE   =  0
Context.MODE_APPEND    = 32768 \\追加
Context.MODE_WORLD_READABLE =  1 \\可读
Context.MODE_WORLD_WRITEABLE =  2 \\可写
以上两个方法都是分别打开文件输入流、输出流,除此之外,Context还提供了如下几个方法来访问应用程序的数据文件夹:
      getDir(String name,int mode) : 在应用程序的数据文件夹下获取或者创建name对应的子目录
       FilegetFilesDir() : 获取该应用程序的数据文件夹的绝对路径
       String[]fileList() : 返回该应用程序的数据文件夹下的指定文件
二:文件存储步骤
1) 在对SD卡进行操作的时候,必须在AndroidManifest.xml清单文件中添加它的授权,在AndroidManifest.xml下的Permissions标签下添加,如下图所示:

2) 进行单元测试,在AndroidManifest.xml下的Instrumentation标签下添加 单元测试,测试内容只需要添加测试名称和包的内容即可,如下图所示:
   
   同时在AndroidManifest.xml 代码中加一个单元测试的标签就可以进行单元测试的内容了:

       <uses-libraryandroid:name="android.test.runner"/>
3) AndroidManifest.xml代码如下:
[html] view
plaincopy

1. 
<?xml version="1.0" encoding="utf-8"?>  
2. 
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
3. 
    package="com.android.sdcarddemo"  
4. 
    android:versionCode="1"  
5. 
    android:versionName="1.0" >  
6. 
  
7. 
    <uses-sdk  
8. 
        android:minSdkVersion="8"  
9. 
        android:targetSdkVersion="17" />  
10.
    <!-- 添加读写SD card 的授权 -->  
11.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
12.
  
13.
    <instrumentation  
14.
        android:name="android.test.InstrumentationTestRunner"  
15.
        android:targetPackage="com.android.sdcarddemo" >  
16.
    </instrumentation>  
17.
  
18.
    <application  
19.
        android:allowBackup="true"  
20.
        android:icon="@drawable/ic_launcher"  
21.
        android:label="@string/app_name"  
22.
        android:theme="@style/AppTheme" >  
23.
        <uses-library android:name="android.test.runner"/>  
24.
        <activity  
25.
            android:name="com.android.sdcarddemo.MainActivity"  
26.
            android:label="@string/app_name" >  
27.
            <intent-filter>  
28.
                <action android:name="android.intent.action.MAIN" />  
29.
  
30.
                <category android:name="android.intent.category.LAUNCHER" />  
31.
            </intent-filter>  
32.
        </activity>  
33.
    </application>  
34.
  
35.
</manifest>  

4) 布局文件 activity_main.xml
[html] view
plaincopy

1. 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
2. 
    xmlns:tools="http://schemas.android.com/tools"  
3. 
    android:layout_width="match_parent"  
4. 
    android:layout_height="match_parent"  
5. 
    android:paddingBottom="@dimen/activity_vertical_margin"  
6. 
    android:paddingLeft="@dimen/activity_horizontal_margin"  
7. 
    android:paddingRight="@dimen/activity_horizontal_margin"  
8. 
    android:paddingTop="@dimen/activity_vertical_margin"  
9. 
    tools:context=".MainActivity" >  
10.
  
11.
    <EditText  
12.
        android:id="@+id/editText1"  
13.
        android:layout_width="wrap_content"  
14.
        android:layout_height="wrap_content"  
15.
        android:layout_alignParentLeft="true"  
16.
        android:layout_alignParentTop="true"  
17.
        android:layout_marginLeft="21dp"  
18.
        android:layout_marginTop="18dp"  
19.
        android:ems="10" >  
20.
    </EditText>  
21.
  
22.
    <Button  
23.
        android:id="@+id/button2"  
24.
        android:layout_width="wrap_content"  
25.
        android:layout_height="wrap_content"  
26.
        android:layout_alignBaseline="@+id/textView1"  
27.
        android:layout_alignBottom="@+id/textView1"  
28.
        android:layout_alignLeft="@+id/button1"  
29.
        android:text="读取信息" />  
30.
  
31.
    <TextView  
32.
        android:id="@+id/textView1"  
33.
        android:layout_width="wrap_content"  
34.
        android:layout_height="wrap_content"  
35.
        android:layout_below="@+id/button1"  
36.
        android:layout_centerHorizontal="true"  
37.
        android:layout_marginTop="40dp" />  
38.
  
39.
    <Button  
40.
        android:id="@+id/button1"  
41.
        android:layout_width="wrap_content"  
42.
        android:layout_height="wrap_content"  
43.
        android:layout_alignLeft="@+id/editText1"  
44.
        android:layout_below="@+id/editText1"  
45.
        android:layout_marginTop="20dp"  
46.
        android:text="保存信息" />  
47.
  
48.
</RelativeLayout>  

5) FileService.java 服务类,用来实现读写SD卡的方法
[java] view
plaincopy

1. 
package com.android.sdcarddemo;  
2. 
  
3. 
import java.io.ByteArrayOutputStream;  
4. 
import java.io.File;  
5. 
import java.io.FileInputStream;  
6. 
import java.io.FileNotFoundException;  
7. 
import java.io.FileOutputStream;  
8. 
import java.io.IOException;  
9. 
  
10.
import android.content.Context;  
11.
import android.os.Environment;  
12.
import android.util.Log;  
13.
import android.widget.Toast;  
14.
  
15.
public class FileService {  
16.
  
17.
    private final static String TAG = "FileService";  
18.
    private Context context;  
19.
  
20.
    public FileService(Context context) {  
21.
        this.context = context;  
22.
    }  
23.
  
24.
    public FileService() {  
25.
    }  
26.
  
27.
    public String getFileFromSdcard(String fileName) {  
28.
        FileInputStream inputStream = null;  
29.
        // 在手机应用开发中 ByteArrayOutputStream 流是缓冲的流,和磁盘无关,可以不需要关闭  
30.
        // Environment.MEDIA_MOUNTED 如果是可读写的状态,并且SD卡是存在的情况下  
31.
        ByteArrayOutputStream outputSteam = new ByteArrayOutputStream();  
32.
        File file = new File(Environment.getExternalStorageDirectory(), fileName);  
33.
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {  
34.
            try {  
35.
                inputStream = new FileInputStream(file);  
36.
                int length = 0;  
37.
                byte[] buffer = new byte[1024];  
38.
                while (-1 != (length = (inputStream.read(buffer)))) {  
39.
                    outputSteam.write(buffer, 0, length);  
40.
                }  
41.
  
42.
            } catch (FileNotFoundException e) {  
43.
                // TODO Auto-generated catch block  
44.
                e.printStackTrace();  
45.
            } catch (IOException e) {  
46.
                // TODO Auto-generated catch block  
47.
                e.printStackTrace();  
48.
            } finally {  
49.
                if (inputStream != null) {  
50.
                    try {  
51.
                        inputStream.close();  
52.
                    } catch (IOException e) {  
53.
                        // TODO Auto-generated catch block  
54.
                        e.printStackTrace();  
55.
                    }  
56.
                }  
57.
            }  
58.
        } else {  
59.
            Toast.makeText(context, "Please input SD card", Toast.LENGTH_LONG).show();  
60.
            Log.i(TAG, "No SD card");  
61.
        }  
62.
  
63.
        return new String(outputSteam.toByteArray());  
64.
    }  
65.
  
66.
    /** 
67.
     * 把内容保存在SD 卡上 
68.
     *  
69.
     * @param fileName 文件的名称 
70.
     * @param content 文件的内容 
71.
     * @return 
72.
     */  
73.
    public boolean saveContentToSDcard(String fileName, String content) {  
74.
        boolean flag = false;  
75.
        FileOutputStream fileOutputStream = null;  
76.
        // 获得SD卡的路径  
77.
        File file = new File(Environment.getExternalStorageDirectory(), fileName);  
78.
        // 判断SD卡是否可以用  
79.
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageDirectory())) {  
80.
            try {  
81.
                fileOutputStream = new FileOutputStream(file);  
82.
                fileOutputStream.write(content.getBytes());  
83.
                flag = true;  
84.
            } catch (FileNotFoundException e) {  
85.
                // TODO Auto-generated catch block  
86.
                e.printStackTrace();  
87.
            } catch (IOException e) {  
88.
                // TODO Auto-generated catch block  
89.
                e.printStackTrace();  
90.
            } finally {  
91.
                if (fileOutputStream != null) {  
92.
                    try {  
93.
                        fileOutputStream.close();  
94.
                    } catch (IOException e) {  
95.
                        // TODO Auto-generated catch block  
96.
                        e.printStackTrace();  
97.
                    }  
98.
                }  
99.
            }  
100.  
        }  
101.  
  
102.  
        return flag;  
103.  
    }  
104.  
}  

 6) 主程序文件 MainActivity.java
[java] view
plaincopy

1. 
package com.android.sdcarddemo;  
2. 
  
3. 
import android.os.Bundle;  
4. 
import android.app.Activity;  
5. 
import android.content.Context;  
6. 
import android.util.Log;  
7. 
import android.view.Menu;  
8. 
import android.view.View;  
9. 
import android.view.View.OnClickListener;  
10.
import android.widget.Button;  
11.
import android.widget.EditText;  
12.
import android.widget.TextView;  
13.
  
14.
public class MainActivity extends Activity {  
15.
      
16.
    private static final String TAG = "MainActivity";  
17.
  
18.
    private Button button;  
19.
    private Button button1;  
20.
    private EditText editText;  
21.
    private TextView textView;  
22.
      
23.
    @Override  
24.
    protected void onCreate(Bundle savedInstanceState) {  
25.
        super.onCreate(savedInstanceState);  
26.
        setContentView(R.layout.activity_main);  
27.
        initComponent();  
28.
        button.setOnClickListener(new OnClickListener() {  
29.
              
30.
            @Override  
31.
            public void onClick(View v) {  
32.
                // TODO Auto-generated method stub  
33.
                MainActivity.this.saveFile();  
34.
            }  
35.
        });  
36.
          
37.
        button1.setOnClickListener(new OnClickListener() {  
38.
              
39.
            @Override  
40.
            public void onClick(View v) {  
41.
                // TODO Auto-generated method stub  
42.
                MainActivity.this.readFile();  
43.
            }  
44.
        });  
45.
    }  
46.
  
47.
    @Override  
48.
    public boolean onCreateOptionsMenu(Menu menu) {  
49.
        // Inflate the menu; this adds items to the action bar if it is present.  
50.
        getMenuInflater().inflate(R.menu.main, menu);  
51.
        return true;  
52.
    }  
53.
      
54.
    private void initComponent(){  
55.
        button = (Button)findViewById(R.id.button1);  
56.
        button1 = (Button)findViewById(R.id.button2);  
57.
        editText = (EditText)findViewById(R.id.editText1);  
58.
        textView = (TextView)findViewById(R.id.textView1);  
59.
          
60.
    }  
61.
      
62.
    private void saveFile(){  
63.
        String str = editText.getText().toString();  
64.
        FileService fileService = new FileService();  
65.
        boolean flag = fileService.saveContentToSDcard("hello.txt", str);  
66.
        Log.i(TAG, "------->> " + flag);  
67.
    }  
68.
      
69.
    private void readFile(){  
70.
        FileService fileService = new FileService(MainActivity.this);  
71.
        String str = fileService.getFileFromSdcard("hello.txt");  
72.
        textView.setText(str);  
73.
    }  
74.
  
75.
}  

程序运行结果:

扩展:
(1)直接从一个文件进行读写,而不是使用editText控件,该怎么实现?
使用 Context类生成对象进行上下文传递
(2)单独建立一个MyTest.java类文件进行单元测试会较好
三:文件存储过程总结
(1)从sdcard上读取文件
判断File是否在sdcard上->建立FileInputStream(new File())对象 ->调用new FileInputStream()对象的read方法读取信息->调用new ByteArrayOutputStream()缓冲流对象的的write方法写入缓冲区中->调用new String(outputStream.toByteArray())对象将缓冲区内容转化为字符串格式
(2)向sdcard保存文件
通过Environment.getExternalStorageDirectory()获得sdcard路径->通过new File(文件路径,文件名称)建立文件->判断sdcard是否可用Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageDirectory())->调用new FileOutputStream(new File())的write方法
 
四:知识点扩充Environment
Environment类[查看AndroidAPI文档]:这个类提供了一些操作系统环境应用的操作,在这里面的
Constants 里面的返回值可以判断出SD卡的状态:装载、卸载、或者是允许可读写的操作
   如下图所示:

   
 
   File file = new File(Environment.getxxxx); //得到扩展存储卡的路径
 
   Eclipse使用技巧:方法前面自动增加注释快捷键是 alt+shift+j
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android开发
相关文章推荐