一、
/data/data/应用程序包名/files目录 下的文件读写
public abstract FileInputStream openFileInput (String name)
打开一个私有目录即/data/data/应用程序包名/files目录下的文件,读入到输入流中,返回的是FileInputStream
public abstract FileOutputStream openFileOutput (String name, int mode)
打开一个私有目录即/data/data/应用程序包名/files目录下的文件,如果这个文件不存在就创建。mode 一般填写 0 或 MODE_PRIVATE(只能本应用访问)
说到内部存储,很多人会把它跟内存联系到一起,其实这真的是两嘛事儿,比如你买回来的手机,
内存 RAM是:逻辑上的,虚拟的控件,用于运行程序的
内部存储 Rom:物理上的,就是一个硬件设备
简单来说,RAM决定了您的手机可以同时运行多少应用程序(包括前台和后台);而ROM决定了您的手机可以存放多少视频、音乐、软件等文件。
内部存储目录: /data/data
apk文件目录:/data/app
二、一个apk文件是怎么被安装到手机上的?
1)构建工程,打包成apk文件
2)上传apk文件到/data/app目录
3)安装后,在/data/data/ 中生产工程包
4)启动清单文件中配置的主界面
三、如果在写代码的过程中源码丢失怎么办?
可以再 /data/app目录中,获得apk文件,通过反编译,就可以找回我们的源代码
应用一:
使用openfileinput() 和 openfileoutput()方法操作内部存储
点击“保存按钮”,保存到内部存储的files目录中的login文件中,如果没有自动创建一个login.xml文件
点击“取出数据”,在下面TextView中显示出来
package com.oldeleven.day16_internalstoragefiles;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private EditText editText_main_username;
private EditText editText_main_pwd;
private Button button_main_store;
private Button button_main_restore;
private TextView textView_main_result;
private static final String FILE_NAME = "login";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
/**
* 初始化控件
*/
private void initView() {
editText_main_username = (EditText) findViewById(R.id.editText_main_username);
editText_main_pwd = (EditText) findViewById(R.id.editText_main_pwd);
button_main_store = (Button) findViewById(R.id.button_main_store);
button_main_restore = (Button) findViewById(R.id.button_main_restore);
textView_main_result = (TextView) findViewById(R.id.textView_main_result);
}
public void onClickView(View view) {
switch (view.getId()){
case R.id.button_main_store:
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(openFileOutput(FILE_NAME,MODE_PRIVATE));
//使用 getText() + ""的形式是为了避免直接使用getText().toString()造成空指针异常
String username = editText_main_username.getText() + "";
String pwd = editText_main_pwd.getText() + "";
bos.write((username+pwd).getBytes());
} catch (java.io.IOException e) {
e.printStackTrace();
}finally {
if (bos!=null){
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
break;
case R.id.button_main_restore:
//取数据并显示到textView_main_result
BufferedInputStream bis = null;
ByteArrayOutputStream baos = null;
try {
bis = new BufferedInputStream(openFileInput(FILE_NAME));
baos = new ByteArrayOutputStream();
byte[] data = new byte[1024*3];
int len = 0;
while ((len = bis.read(data)) != -1){
baos.write(data,0,len);
baos.flush();
}
textView_main_result.setText(baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (baos != null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
break;
}
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<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="com.oldeleven.day16_internalstoragefiles.MainActivity">
<EditText
android:id="@+id/editText_main_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入用户名"/>
<EditText
android:id="@+id/editText_main_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/editText_main_username"
android:hint="请输入密码"/>
<Button
android:id="@+id/button_main_store"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/editText_main_pwd"
android:text="保存数据到内部存储files中去"
android:onClick="onClickView"/>
<Button
android:id="@+id/button_main_restore"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button_main_store"
android:text="取出数据"
android:onClick="onClickView"/>
<TextView
android:id="@+id/textView_main_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/button_main_restore"
android:text="Hello World!"
android:background="#0f0"/>
</RelativeLayout>
代码优化:
public final class CloseUtils {
private CloseUtils(){}
public static void closeQuietly(Closeable closeable){
if (null != closeable){
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
上面的工具类主要用户关闭流对象,关闭流对象一行代码,每次加那么多的try..catch 块很麻烦。java中有一个Closeable 接口,该接口标志了一个可关闭的对象。它只有一个close方法。
所以上面的代码优化后如下:
大致的代码片段如下,在finally中:
while ((len = bis.read(data)) != -1){
baos.write(data,0,len);
baos.flush();
}
textView_main_result.setText(baos.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
CloseUtils.closeQuietly(bis);
CloseUtils.closeQuietly(baos);
}
break;