5.1读写文件
5.1.1 需求分析效果图
5.1.2.设计思路与步骤
1.首先布局,就不多说了。线性搞定,两个EditText,两个Button,注意两个Button是在一个水平显示的所以要嵌套在另一个LinearLayout中去即可。
2.显然四个控制都必须有id,要在两个Button上写onClick事件对应的方法,由于都是写文件业务差不多,就用一个方法了。那么用一个方法,如何来判断是哪个按钮点过来的呢?
3.通过在public void onClick(View view)方法体中,可以拿到view对象,通过view.getId分别与两个Button的id比较,与哪个一致就点击了哪个,就写入到ROM或SD卡中去。
4.关键是写入到ROM中,怎么获取ROM的输出流或拿到路径呢,通过Context的openFileOutput(“文件名”,”模式Context.MODE_PRIVATE等”)方法即可直接拿到输出流。而写入到SD中,怎么获取SD的输出流或拿到SD卡路径呢?可以通过Environment.getExternalStorageDirectory()方法获取当前的SDCard位置(方法返回代表SD卡路径的File对象),有些File对象后,重新构造一个具体文件File f = new File(sdFile,”文件名.txt”)。再把f扔进FileOutputStream即可输出文件到sd卡了。
5.需要注意的是,写入SD卡是需要注册权限的,writer_external_storage。
? 写入文件到SD卡
? 需要在清单文件中注册权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
? 2.1版本以下的SDCard位置和2.2之后版本不同。之后都在/mnt/sdcard
可以通过Environment.getExternalStorageDirectory()获取当前SDCard位置,兼容所有版本。返回的是一个代表/mnt/sdscard这样的File对象。
通过sdFile对象,与用户输入的文件名,构建具体的文件File realFile = new File(sdFile, fileName);,将realFile传入FileOutputStream即可写入文件。
? 获取SDCard状态
通过Environment.getExternalStorageState()方法获取SDCard当前状态
常量 Environment.MEDIA_MOUNTED 为已安装状态
通过判断这两个状态是否一致,来将”保存至SD卡”按钮对象sdBT。通过sdBT.setEnable(true),设置成可点击或setEnable(false)不可点击。
或者直接sdBT.setVisibility(View.VISIBLE或View.INVISIBLE)
? 写入文件至手机
? 通过Context.openFileOutput(String name, int mode)可以获取一个文件输出流
name为文件名,mode为文件模式,有4种模式
输出流指向路径为:/data/data/包名/files/
? 文件模式在Context中有定义常量
MODE_PRIVATE私有 ---- 默认的
MODE_WORLD_READABLE其他程序可读(不可写)
MODE_WORLD_WRITEABLE其他程序可写(不可读)
模式可以组合使用,例如:MODE_WORLD_READABLE + MODE_WORLD_WRITEABLE
MODE_APPEND追加
? 从手机中读取文件
? 通过Context.openFileInput(String name)可以获取一个文件输入流
该输入流可以读取 /data/data/包名/files/ 路径下的文件
? 获取当前程序Files文件路径
ContextWrapper.getFilesDir() 返回路径为/data/data/包名/files的File对象。也可以通过此文件路径,进行读取写入手机文件。
5.1.3 核心示例代码:
/**
* view.getId可得到传入view中的实际控件的id是什么
* @param view
*/
public void onClick(View view) {
try{
String filename = filenameET.getText().toString();
String filecontent = filecontentET.getText().toString();
switch (view.getId()) {
case R.id.sdBT:
fileService.saveFileToSD(filename,filecontent);
break;
case R.id.ramBT:
fileService.saveFileToRAM(filename,filecontent);
break;
default:
break;
}
filecontentET.setText("");
filenameET.setText("");
Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_SHORT).show();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(), "保存失败", Toast.LENGTH_SHORT).show();
}
}
/**
* activity每次被重新激活时,可以调用此方法。比如若从当前的File应用中,切换应用到设置-装载卸载SD卡后。
* 又切换回来时,此方法会被执行。
*/
@Override
protected void onResume() {
/*if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
findViewById(R.id.sdBT).setVisibility(View.INVISIBLE);
}else{
findViewById(R.id.sdBT).setVisibility(View.VISIBLE);//可直接根据是否是挂载状态来决定显示与否
}*/
//根据是否是挂载状态来决定,按钮是否可点击
findViewById(R.id.sdBT).setEnabled(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED));
super.onResume();
}
........................FileService中的代码........................................
public void saveFileToSD(String filename, String filecontent) throws IOException {
File sdFile = Environment.getExternalStorageDirectory();//怎么得到sd卡的文件路径 呢,通过Environment来搞定
FileOutputStream out = new FileOutputStream(new File(sdFile,filename));
out.write(filecontent.getBytes());
out.close();
System.out.println("sd卡共用了多少空间:"+sdFile.getTotalSpace());
System.out.println("sd卡还剩余多少空间"+sdFile.getFreeSpace());
}
public void saveFileToRAM(String filename, String filecontent) throws IOException {
//通过context应用上下文获取,打开一个输入流,此流开启关联的是RAM手机/data/data/包名/files文件夹的
//若files文件夹不存在则创建一个文件夹,存在直接将要创建的文件名扔进去即可。
FileOutputStream out = context.openFileOutput(filename, Context.MODE_PRIVATE);
out.write(filecontent.getBytes());
out.close();
}
5.1.4 Enviroment类与Context类的相关了解
Environment类:
环境,似乎只与linux操作下挂载相关的外设硬件如u盘、光驱等等硬件,外挂设备在此linux中相关的状态有关系。比如:Environment.getExternalStorageState()方法获取SDCard当前状态,Environment.MEDIA_MOUNTED 为已安装状态,Environment.getExternalStorageDirectory()获取sd卡位置。
Context类:
Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities,broadcasting and receiving intents, etc.
简单的理解就是提供一个全局的应用级的相关信息,包括应用级的资源、类文件及应用级的操作比如发布生命周期、广播和接收意图等。
比如context.openFileIntput或openFileOutput、---对应data-data文件夹下包名-files文件夹的文件流对象,与context.getFilesDir....包名-files的对象File或context.getCacheDir... 包名-cache的对象File。
context.getSharedPerfernces拿到SharedPerferences对象,也是和data-data文件夹下包名-shared_perfs文件夹下各文件相关。
获取数据库打开SQLiteOpenHelper对象,也构造方法需要一个context,对应的文件夹就是data-data文件夹下包名-databases文件夹下各文件相关。