【Android 开发】:数据存储之File文件存储 [即SD卡的写入与读取]

    在实际开发中,Android提供了5种方式存储数据,从这一讲开始,我们来学习一下Android中的数据存储。
1. 文件存储数据 [也就是通常说的SD卡中] 
2. 使用SharedPreferences存储数据  
3. SQLite数据库存储数据  
4. 使用ContentProvider存储数据  
5. 网络存储数据 [可以把本地的数据存储在网络的服务端]

1. 文件存储数据介绍


   我们都知道Java提供了一套完整的IO流体系,包括FileInputStream和FileOutStream等,通过这些类我们可以方便的访问磁盘上的文件内容
Android同样支持这种方式访问手机存储器上的文件。
   OpenFileOutput和openFileInput的使用, Context提供了如下两个方法来打开应用程序的数据文件夹里的文件IO流。
1) FileInputStream openFileInput(String name):打开应用程序的数据文件夹下的name文件对应的输入流
2) FileOutStream openFileOutput(String name,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对应的子目录
       File getFilesDir() : 获取该应用程序的数据文件夹的绝对路径
       String[] fileList() : 返回该应用程序的数据文件夹下的指定文件

2. 文件存储步骤

在进行文件存储的时候,都会首先去判断是否存在外部存储设备。

   查看 Android文档 :Using the External Storage [使用可扩展的存储设备]
     每一台Android设备都会支持 "可扩展存储" 的设备来让你保存文件. 它是可以移动的存储设备(例如SD卡)或者集成的(不可移动)的存储设备。
检查媒体存在:
     在你做任何外部存储工作之前,你应该调用 getExternalStorageState()  方法来检查存储媒体是否可以用。这些存储媒体状态可能是已安装,没有存储卡,只读,或者其他的一些状态。

3. 程序实现

1) 在对SD卡进行操作的时候,必须在AndroidManifest.xml清单文件中添加它的授权,在AndroidManifest.xml下的Permissions标签下添加,如下图所示:

2) 进行单元测试,在AndroidManifest.xml下的Instrumentation标签下添加 单元测试,测试内容只需要添加测试名称和包的内容即可,如下图所示:

  

   同时在 AndroidManifest.xml 代码中加一个单元测试的标签就可以进行单元测试的内容了
       <uses-library android:name="android.test.runner"/>
3) AndroidManifest.xml 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.sdcarddemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <!-- 添加读写SD card 的授权 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.android.sdcarddemo" >
    </instrumentation>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library android:name="android.test.runner"/>
        <activity
            android:name="com.android.sdcarddemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
4) 布局文件 activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/editText1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="21dp"
        android:layout_marginTop="18dp"
        android:ems="10" >
    </EditText>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/textView1"
        android:layout_alignBottom="@+id/textView1"
        android:layout_alignLeft="@+id/button1"
        android:text="读取信息" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="40dp" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/editText1"
        android:layout_below="@+id/editText1"
        android:layout_marginTop="20dp"
        android:text="保存信息" />

</RelativeLayout>
5) FileService.java 服务类,用来实现读写SD卡的方法
package com.android.sdcarddemo;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

public class FileService {

    private final static String TAG = "FileService";
    private Context context;

    public FileService(Context context) {
        this.context = context;
    }

    public FileService() {
    }

    public String getFileFromSdcard(String fileName) {
        FileInputStream inputStream = null;
        // 在手机应用开发中 ByteArrayOutputStream 流是缓冲的流,和磁盘无关,可以不需要关闭
        // Environment.MEDIA_MOUNTED 如果是可读写的状态,并且SD卡是存在的情况下
        ByteArrayOutputStream outputSteam = new ByteArrayOutputStream();
        File file = new File(Environment.getExternalStorageDirectory(), fileName);
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
            try {
                inputStream = new FileInputStream(file);
                int length = 0;
                byte[] buffer = new byte[1024];
                while (-1 != (length = (inputStream.read(buffer)))) {
                    outputSteam.write(buffer, 0, length);
                }

            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        } else {
            Toast.makeText(context, "Please input SD card", Toast.LENGTH_LONG).show();
            Log.i(TAG, "No SD card");
        }

        return new String(outputSteam.toByteArray());
    }

    /**
     * 把内容保存在SD 卡上
     * 
     * @param fileName 文件的名称
     * @param content 文件的内容
     * @return
     */
    public boolean saveContentToSDcard(String fileName, String content) {
        boolean flag = false;
        FileOutputStream fileOutputStream = null;
        // 获得SD卡的路径
        File file = new File(Environment.getExternalStorageDirectory(), fileName);
        // 判断SD卡是否可以用
        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageDirectory())) {
            try {
                fileOutputStream = new FileOutputStream(file);
                fileOutputStream.write(content.getBytes());
                flag = true;
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (fileOutputStream != null) {
                    try {
                        fileOutputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }

        return flag;
    }
}
  6) 主程序文件 MainActivity.java
package com.android.sdcarddemo;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
    
    private static final String TAG = "MainActivity";

    private Button button;
    private Button button1;
    private EditText editText;
    private TextView textView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initComponent();
        button.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                MainActivity.this.saveFile();
            }
        });
        
        button1.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                MainActivity.this.readFile();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
    private void initComponent(){
        button = (Button)findViewById(R.id.button1);
        button1 = (Button)findViewById(R.id.button2);
        editText = (EditText)findViewById(R.id.editText1);
        textView = (TextView)findViewById(R.id.textView1);
        
    }
    
    private void saveFile(){
        String str = editText.getText().toString();
        FileService fileService = new FileService();
        boolean flag = fileService.saveContentToSDcard("hello.txt", str);
        Log.i(TAG, "------->> " + flag);
    }
    
    private void readFile(){
        FileService fileService = new FileService(MainActivity.this);
        String str = fileService.getFileFromSdcard("hello.txt");
        textView.setText(str);
    }

}

4. 程序执行结果


5. 备注知识点

   Environment类[查看Android API文档]:这个类提供了一些操作系统环境应用的操作,在这里面的 Constants 里面的返回值可以判断出SD卡的状态:装载、卸载、或者是允许可读写的操作
   如下图所示:
  
 
   File file = new File(Environment.getxxxx); //得到扩展存储卡的路径
 
   Eclipse使用技巧:方法前面自动增加注释快捷键是 alt+shift+j
 
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值