Android File存储

一、openFileOutput和openFileInput

Context提供了如下两个方法来打开本应用程序的数据文件夹里的文件I/O流。

》FileInputStream openFileInput(String name):打开应用程序的数据文件夹下的name文件对应输入流。

》FileOutputStream openFileOutput(String name, int mode):打开应用程序的数据文件夹下的name文件对应输入流。

上面两个方法分别用于打开文件输入流、输出流,其中第二个方法的第二个参数指定打开文件的模式,该模式支持如下值。

》MODE_PRIVATE:该文件只能被当前程序读写。

》MODE_APPEND:以追加方式打开该文件,应用程序可以向该文件中追加内容。

》MODE_WORLD_READABLE:该文件的内容可以被其他程序读取。

》MODE_WORLD_WRITEABLE:该文件的内容可由其他程序读、写。

除此之外,Context还提供了如下几个方法来访问应用程序的数据文件夹。

》getDir(String name, int mode):在应用程序的数据文件夹下获取或创建name对应的子目录。

》File getFilesDir():获取该应用程序的数据文件夹的绝对路径。

》String[] fileList():返回该应用程序的数据文件夹下的全部文件。

》deleteFile(String name):删除该应用程序的数据文件夹下的指定文件。

下面是一个简单的用openFileOutput和openFileInput读、写文件的demo

1、Activity文件

package com.example.androidioanddatastore.sdcode;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

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

import com.example.androidioanddatastore.R;

/**
 * 使用openFileOutput和openFileInput读、取文件的例子
 * @author Administrator
 *
 */
public class FileActivity extends Activity {
	public final static String FILE_NAME = "file_data.bin";
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_file);
		System.out.println(new StringBuffer("a").append("b").append("c").toString());
		//获取两个按钮
		Button readBtn = (Button) findViewById(R.id.read_btn);
		Button writeBtn = (Button) findViewById(R.id.write_btn);
		//获取两个文本框
		final EditText readEdit = (EditText) findViewById(R.id.read_edit);
		final EditText writeEdit = (EditText) findViewById(R.id.write_edit);
		//为writeBtn按钮绑定监听器
		writeBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				//将writeEdit的内容写入文件中
				write(writeEdit.getText().toString());
				writeEdit.setText("");
				
			}
		});
		//为readBtn按钮绑定监听器
		readBtn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				//读取指定文件中的内容,并显示出来
				readEdit.setText(read());
			}
		});
	}
	
	
	
	protected String read() {
		try {
			//打开输入流
			FileInputStream fileInputStream = openFileInput(FILE_NAME);
			byte[] buff = new byte[2048];
			int hasRead = 0;
			StringBuilder builder = new StringBuilder("");
			//读取文件内容
			while ((hasRead = fileInputStream.read(buff)) > 0) {
				builder.append(new String(buff , 0 , hasRead));
			}
			//关闭输入流
			fileInputStream.close();
			return builder.toString();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}



	private void write(String content){
		try {
			//以追加模式打开输入流
			FileOutputStream fileOutputStream = openFileOutput(FILE_NAME, Context.MODE_APPEND);
			//将FileOutputStream包装成PaintStream
			PrintStream printStream = new PrintStream(fileOutputStream);
			//输出文件内容
			printStream.println(content);
			//关闭输入流
			printStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
}
2、布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/read_edit"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <Button
        android:id="@+id/read_btn"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="read" />

    <EditText
        android:id="@+id/write_edit"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <Button
        android:id="@+id/write_btn"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="write" />

</LinearLayout>
当输入的内容保存到应用程序的数据文件夹中后,打开File Explorer面板后,可以在/data/data/<package name>/files目录下找到保存的文件。


二、读取SD卡上的文件

为了更好的存、取应用程序的大文件数据,应用程序需要读、写SD卡上的文件。SD卡大大扩充手机的存储能力。

读、写SD上的文件请按如下步骤进行。

(1)调用Environment的getExternalStorageState()方法判断手机上是否插入了SD卡,并且应用程序具有读写SD卡的权限。例如使用如下代码:

// 如果手机插入了SD卡,而且应用程序具有访问SD卡的权限

Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
(2)调用Environment的getExternalStorageDirectory()方法来获取外部存储器,也就是SD卡的目录。

(3)使用FileInputStream、FileOutputStream、FileReader或FIleWriter读、写SD卡里的文件。

应用程序读、写SD卡的文件有如下两个注意点:

》手机上应该已插入SD卡。对于模拟器来说,可通过mksdcord命令来创建虚拟存储卡。

》为了读、写SD卡上的数据,必须在应用程序的清单文件中添加读、写SD卡的权限。例如如下配置:

<!-- 在SD卡中创建与删除文件的权限 -->
  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <!-- 向SD卡写入数据权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
   
下面的demo示范了如何读、写SD卡上的文件。这个demo的布局文件与上一个demo完全一样。

package com.example.androidioanddatastore.sdcode;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;

import com.example.androidioanddatastore.R;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class SDCodeActivity extends Activity {
	public final static String FILE_NAME = "/file_data.bin";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_file);
		System.out.println(new StringBuffer("a").append("b").append("c")
				.toString());
		// 获取两个按钮
		Button readBtn = (Button) findViewById(R.id.read_btn);
		Button writeBtn = (Button) findViewById(R.id.write_btn);
		// 获取两个文本框
		final EditText readEdit = (EditText) findViewById(R.id.read_edit);
		final EditText writeEdit = (EditText) findViewById(R.id.write_edit);
		// 为writeBtn按钮绑定监听器
		writeBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 将writeEdit的内容写入文件中
				write(writeEdit.getText().toString());
				writeEdit.setText("");

			}
		});
		// 为readBtn按钮绑定监听器
		readBtn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// 读取指定文件中的内容,并显示出来
				readEdit.setText(read());
			}
		});
	}

	protected String read() {
		try {
			// 如果手机插入了SD卡,而且应用程序具有访问SD卡的权限
			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
				// 获取SD卡目录
				File sdCodeDir = Environment.getExternalStorageDirectory();
				FileInputStream fileInputStream = new FileInputStream(sdCodeDir.getCanonicalPath() + FILE_NAME);
				//将指定输入流包装成BufferedReader
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
				StringBuilder builder = new StringBuilder("");
				String line = "";
				//循环读取内容
				while ((line = bufferedReader.readLine()) != null) {
					builder.append(line);
				}
				//关闭输入流
				bufferedReader.close();
				return builder.toString();
			}
		} catch (IOException e) {
		}
		return null;
	}

	protected void write(String content) {
		try {
			// 如果手机插入了SD卡,而且应用程序具有访问SD卡的权限
			if (Environment.getExternalStorageState().equals(
					Environment.MEDIA_MOUNTED)) {
				// 获取SD卡目录
				File sdCodeDir = Environment.getExternalStorageDirectory();
				File targetFile = new File(sdCodeDir.getCanonicalPath()
						+ FILE_NAME);
				// 以指定文件创建RandomAccessFile对象
				RandomAccessFile accessFile = new RandomAccessFile(targetFile,
						"rw");
				// 将文件记录指针移动最后
				accessFile.seek(targetFile.length());
				// 输出文件内容
				accessFile.write(content.getBytes());
				// 关闭RandomAccessFile
				accessFile.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
提示:

如果不想使用Environment.getExternalStorageDirectory()这么复杂的语句来获取SD卡的路径,完全可以使用/mnt/sdcard/路径代表SD卡的路径,然后程序通过判断/mnt/sdcard/路径是否存在就可知道手机是否已经插入SD卡。


SD卡文件浏览器

下面是利用Java的File类开发一个SD卡文件浏览器,该程序直接使用/mnt/sdcard/来访问系统的SD卡目录,然后通过File的listFiles()方法来获取指定目录下的全部文件和文件夹。

1.程序的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <!-- 显示当前路径的文本框 -->
    <TextView 
        android:id="@+id/explorer_path"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"/>
    <!-- 列出当前路径下的所有文件的ListView -->
    <ListView 
        android:id="@+id/explorer_listview" 
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:divider="#000"
        android:dividerHeight="1dp"/>
    <!-- 返回上一级目录的按钮 -->
    <Button 
        android:id="@+id/explorer_parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_menu_back"
        />
    
    
    
    
    

</LinearLayout>
2.item文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <ImageView 
        android:id="@+id/item_explorer_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView 
        android:id="@+id/item_explorer_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>
3.activity文件

package com.example.androidioanddatastore.sdcode;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.example.androidioanddatastore.R;

/***
 * SD卡文件浏览器demo
 * 
 * @author Administrator
 * 
 */
public class SDFileExplorerActivity extends Activity {
	public final static String SDFilePath = "/mnt/sdcard/";
	/** 显示内容的ListView */
	private ListView mListView;
	/** 显示当前的目录路径 */
	private TextView mTextView;
	/** 返回上一级按钮 **/
	private Button mBtn;
	/** 记录当前的父文件夹 */
	private File currentParent;
	/** 记录当前目录下的所有文件的文件数组 */
	private File[] currentFiles;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_sd_file_explorer);
		// 初始化组件
		initView(this);
		// 初始化源数据
		initData(this);
		// 为组件绑定事件监听器
		initEvent();

	}

	/**
	 * 初始化事件监听器
	 */
	private void initEvent() {
		// 为ListView列表项绑定点击事件监听器
		mListView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// 用户点击了文件,直接返回,不做任何处理
				if (currentFiles[position].isFile()) {
					return;
				}
				// 获取用户单击的文件夹下的所有文件
				File[] tmp = currentFiles[position].listFiles();
				if (tmp == null || tmp.length <= 0) {
					Toast.makeText(SDFileExplorerActivity.this,
							"当前路径不可访问或该路径下没有文件", Toast.LENGTH_SHORT).show();
				} else {
					// 获取用户单击的列表项对应的文件夹,设为当前的父文件夹
					currentParent = currentFiles[position];
					// 保存当前的文件夹内的全部文件和文件夹
					currentFiles = tmp;
					// 再次更新ListView
					inflateListView(tmp);
				}
			}
		});
		mBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				try {
					if (!currentParent.getCanonicalPath().equals(SDFilePath)) {
						//获取上级目录
						currentParent = currentParent.getParentFile();
						//列出当前目录下的所有文件
						currentFiles = currentParent.listFiles();
						//再次更新ListView
						inflateListView(currentFiles);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});

	}

	/***
	 * 初始化数据
	 * 
	 * @param context
	 */
	private void initData(Context context) {
		// 获得系统的SDCode的目录
		File root = new File(SDFilePath);
		// 如果文件夹存在,即SD卡存在
		if (root.exists()) {
			currentParent = root;
			// 获取root文件夹下的所有文件
			currentFiles = root.listFiles();
			// 使用当前目录下的全部文件、文件夹来填充ListView
			inflateListView(currentFiles);
		}
	}

	/**
	 * 填充ListView数据
	 * 
	 * @param currentFiles
	 *            File[]数据
	 */
	private void inflateListView(File[] files) {
		// 创建一个List集合,List集合的元素是Map
		List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < files.length; i++) {
			Map<String, Object> listItem = new HashMap<String, Object>();
			// 判断当前File是文件夹,使用文件夹图标;否则使用文件图标
			if (files[i].isDirectory()) {
				listItem.put("icon", R.drawable.ic_menu_copy);
			} else {
				listItem.put("icon", R.drawable.ic_menu_copy_holo_light);
			}
			// 保存文件夹或者文件的name
			listItem.put("fileName", files[i].getName());
			// 添加List项
			listItems.add(listItem);
		}
		// 创建一个SimpleAdapter
		SimpleAdapter adapter = new SimpleAdapter(SDFileExplorerActivity.this,
				listItems, R.layout.item_files_explorer, new String[] { "icon",
						"fileName" }, new int[] { R.id.item_explorer_icon,
						R.id.item_explorer_name });
		// 为ListView设置Adapter
		mListView.setAdapter(adapter);
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				try {
					mTextView.setText("当前路径为:"
							+ currentParent.getCanonicalPath());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
	}

	/***
	 * 初始化组件
	 * 
	 * @param context
	 */
	private void initView(Context context) {
		mListView = (ListView) findViewById(R.id.explorer_listview);
		mTextView = (TextView) findViewById(R.id.explorer_path);
		mBtn = (Button) findViewById(R.id.explorer_parent);
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值