之前一直不理解java中文件读写的原理。只知道从网上copy一段代码过来,能够正常运行则证明没有问题。今天,决定好好理解一下文件读写的原理。
首先,我们来理解一下流的概念。
流:是指通过一定的传播路径从源传递到目的地字节序列。
在java中,以流的形式来处理所有的输入输出。
可以看到,java中流分为两种。字符流和字节流。
字符流与字节流的区别:
其操作代码本身就是不同的。
字节流在操作的时候本身是不会用到缓冲区的。是与文件本身直接操作。而字符流在操作的时候是使用到缓冲区的。
字节流在操作文件的时候,即使不关闭资源,文件也能输出。但是如果字符流不适用close方法的话,则不会输出任何内容。说明字符流用的是缓冲区。
1、利用字节流对文件进行简单的读写。
package filetest;
/**
* 运用字节流对文件进行读写。
* */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test01 {
<span style="white-space:pre"> </span>static File file = new File("E:\\NonShan.txt");
<span style="white-space:pre"> </span>public static void main(String[] args) {
<span style="white-space:pre"> </span>Test01 test01 = new Test01();
<span style="white-space:pre"> </span>test01.readText();
<span style="white-space:pre"> </span>test01.writeText();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//写文件
<span style="white-space:pre"> </span>public void writeText(){
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>FileOutputStream outputStream = new FileOutputStream(file,true);//值为true则表示不覆盖原来的内容。
<span style="white-space:pre"> </span>//有中文,存在乱码问题。
<span style="white-space:pre"> </span>//由于中文占两个字节,英文只占一个字节。当用数组读取时,中文字有可能就被拆分。
<span style="white-space:pre"> </span>String content = "hi~好开心呀123";
<span style="white-space:pre"> </span>outputStream.write(content.getBytes());
<span style="white-space:pre"> </span>outputStream.close();
<span style="white-space:pre"> </span>} catch (Exception e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>//读文件
<span style="white-space:pre"> </span>public void readText(){
<span style="white-space:pre"> </span>try {
<span style="white-space:pre"> </span>FileInputStream inputStream = new FileInputStream(file);
<span style="white-space:pre"> </span>byte[] b = new byte[100];
<span style="white-space:pre"> </span>inputStream.read(b, 0, b.length);
<span style="white-space:pre"> </span>System.out.println(new String(b));
<span style="white-space:pre"> </span>inputStream.close();
<span style="white-space:pre"> </span>} catch (Exception e) {
<span style="white-space:pre"> </span>e.printStackTrace();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
}
2、利用字符流对文件进行简单的读写。
package filetest;
/**
* 字符流的读写
* 依旧存在乱码问题。
* */
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class Test02 {
File file = new File("E:\\NonShan.txt");
public static void main(String[] args) {
Test02 test02 = new Test02();
test02.readText();
test02.writeText();
}
//读文件
public void readText(){
try {
FileReader fileReader = new FileReader(file);
int i = 0;
String s = "";
while((i=fileReader.read())!=-1){
s = s + (char)i;
}
System.out.println(s);
fileReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//写文件
public void writeText(){
try {
FileWriter fileWriter = new FileWriter(file,true);
String content = "haha哈哈哈";
fileWriter.write(content);
fileWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、文件读写流使用buffer封装。
①字节流读写
package filetest;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class Test03 {
File file = new File("E:\\NonShan.txt");
public static void main(String[] args) {
Test03 test03 = new Test03();
test03.writeText();
test03.readText();
}
//写文件
public void writeText() {
try {
FileOutputStream outputStream = new FileOutputStream(file,true);
BufferedOutputStream bStream = new BufferedOutputStream(outputStream);
String content = "12333你好 456 aaa";
bStream.write(content.getBytes());
bStream.close();//当使用到缓冲区的时候一定要close,否则得不到结果。
} catch (Exception e) {
e.printStackTrace();
}
}
//读文件
public void readText(){
try {
FileInputStream inputStream = new FileInputStream(file);
BufferedInputStream bInputStream = new BufferedInputStream(inputStream);
byte[] b = new byte[160];
bInputStream.read(b);
bInputStream.close();
System.out.println(new String(b));
} catch (Exception e) {
e.printStackTrace();
}
}
}
②字符流读写
package filetest;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
public class Test04 {
File file = new File("E:\\NonShan.txt");
public static void main(String[] args) {
Test04 test04 = new Test04();
test04.readText();
test04.writeText();
}
//读文件
public void readText(){
try {
FileReader fileReader = new FileReader(file);
BufferedReader bReader = new BufferedReader(fileReader);
String s = "";
String temp = null;
while((temp=bReader.readLine())!=null){
s = s+temp;
}
System.out.println(s);
bReader.close();
fileReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void writeText(){
try {
FileWriter fileWriter = new FileWriter(file,true);
BufferedWriter writer = new BufferedWriter(fileWriter);
writer.write("哈哈哈哈6666623333");
writer.close();
fileWriter.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
但是很多代码中是这样写的。
public void check(String content){
boolean ok = true;
try {
File file = new File("E:\\data structure experiment\\sensitivewords.txt");
if(!file.exists()){
file.createNewFile();
}
//读取文件中的内容
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(file),"gbk"));
while ( br.readLine()!= null) {
//一行一行的读取
String findString = br.readLine();
if(findString!=null&&findString.length()>1){
//将读取到的一行中的内容提取出来。即提取出每一行中#号以外的东西。trim是去除空格。
String find = findString.trim().substring(0,findString.length()-1);
if(content.contains(find)){
JOptionPane.showMessageDialog(contentPane, "存在敏感字符"+find);
ok = false;
}
}
}
if(ok){
JOptionPane.showMessageDialog(contentPane, "不存在敏感字符");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里面
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(file),"gbk")); <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
刚开始是字节流,后来又变成了字符流。
InputStreamReader是字符流和字节流之间的转换中介。