首先,我们创建文件(android6.0及以下,也就是API 23及以下示范)
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FileOutputStream fos = null;
BufferedWriter bw = null;
try {
/*
Android首先反对它,然后完全删除它。
MODE_WORLD_READABLE在版本上被否决,
直到Android M。但在Android N它不再被支持并抛出SecurityException
*/
fos = openFileOutput("readable.txt", MODE_WORLD_READABLE);
bw = new BufferedWriter(new OutputStreamWriter(fos));
bw.write("data");
bw.close();
fos = openFileOutput("writeable.txt", MODE_WORLD_WRITEABLE);
bw = new BufferedWriter(new OutputStreamWriter(fos));
bw.write("data");
bw.close();
fos = openFileOutput("public.txt", MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE);
bw = new BufferedWriter(new OutputStreamWriter(fos));
bw.write("data");
bw.close();
fos = openFileOutput("private.txt", MODE_PRIVATE);
bw = new BufferedWriter(new OutputStreamWriter(fos));
bw.write("data");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch(IOException e){
e.printStackTrace();
}
}
}
}
关于MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE,这两种模式过于危险,很容易引起应用的安全性漏洞,已经在android4.2版本中废弃。
Android首先反对它,然后准备删除它,MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE在版本上被否决,在android6.0及以前仍可以使用这些废弃的不安全方法,直到Android 7.0禁止使用。
如果是android7.0及以上(也就是API 24及以上),会出现下面错误
在Android 7.0及以上它不再被支持并抛出SecurityException
在7.0中,创建文件全部用MODE_PRIVATE
只能看到以下情况
所以最后一组权限,也就是其他用户组权限全部是-(7.0版本及以后最后一组权限只能是-,哪怕最后一组权限是MODE_APPEND也全部是-),也就是其他用户组无权操作,所以另一个app是无法读取该app的数据的。
就像以前的单机游戏,修改数据直接通关的情况都有,然而在7.0之后是不可以读取的,也就没办法正确修改里面文件达到自己的目的。
下面我们来看在6.0及以下版本
openFileOutput("readable.txt", MODE_WORLD_READABLE);
openFileOutput("writeable.txt", MODE_WORLD_WRITEABLE);
openFileOutput("public.txt", MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE);
openFileOutput("private.txt", MODE_PRIVATE);
那么如下图
MODE_PRIVATE 模式写出来的文件最后一组权限是 --- (无任何权限)
MODE_WORLD_READABLE | MODE_WORLD_WRITEABLE 模式写出来的文件最后一组权限是 rw- (可读写)
MODE_WORLD_READABLE 模式写出来的文件最后一组权限是 r-- (只有读权限)
MODE_WORLD_WRITEABLE 模式写出来的文件最后一组权限是 -w- (只有写权限)
用另一个Demo测试
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void button(View view) {
/*
读取其他应用程序的文件在android6.0
*/
try (BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("/data/data/com.example.createfile/files/readable.txt")));) {
String line = br.readLine();
Toast.makeText(this, line, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, "读取失败", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
当读取或者写入的文件是其他应用程序目录下的子目录的文件时,并且拥有对应的读或写的权限时,当前的app不需要在清单文件androidManifest.xml申请额外权限,可直接操作。
如果读取readable.txt或者public.txt
结果如下:
如果读取private.txt或者writeable.txt
结果如下:
7.0以后安全系数有所提高,再者写文件推荐MODE_PRIVATE模式,也只能这个模式,因为现在大多数手机都是在7.0以上,目前我的手机是8.0系统了。
接下来看一下写入其他app数据的情况,可覆盖别的app数据达到自己的目的
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void button(View view) {
/*
读取其他应用程序的文件在android6.0
*/
try (BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream("/data/data/com.example.createfile/files/writeable.txt")));) {
String line = br.readLine();
Toast.makeText(this, line, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, "读取失败", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
// 向别的应用程序子目录写数据,可覆盖它的数据
public void button2(View view) {
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("/data/data/com.example.createfile/files/public.txt")));){
bw.write("我要重写这个public.txt中的数据");
Toast.makeText(this, "写入成功!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, "操作失败", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
点击Button2,结果如下:
来看看public.txt里面的内容
原来里面的内容"data" 已经被修改为"我要重写这个public.txt中的数据"
如果写private.txt和readable.txt是会失败的,如下图
同理,大家也可以测试得到public.txt和writeable.txt里面的文件是可以重写的,private.txt和readable.txt里面的内容是不能重写的,因为没有对应的写权限。
========================================Talk is cheap, show me the code=======================================