又开始回头重新补Java基础了,以前也是去网上直接下代码,这样导致自己只会用,对Java IO流内部机制并不熟悉,实实在在的一个代码搬运工。痛定思痛,觉得自己不能这么干了。基础最为重要,回头重新研究。好了,废话不多说,开扯。一开始我也是只是去网上搜搜看看别人怎么讲。哎,听的糊里糊涂的,不过看的多了,也就慢慢懂了一些。现在就把我理解的总结下。
1.字节流
1)输入字节流 InputStream
基本方法:
InputStream in = new InputStream(file) / /file是文件名
int b = in.read(); 读取一个byte无符号填充到int底八位,-1是EOF
int.read(byte[] buf) 读取数据填充到buf中
int.read(byte[] buf,int start,int size) 读取数据填充到buf中
in.close 关闭输入流
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class FileInputStream_Test {
public static void main(String[] args) throws IOException {
//方式一
InputStream in =new FileInputStream("D:/test.txt");
byte b[] = new byte[in.available()];
in.read(b); //直接把所有字节读入byte数组
System.out.println(new String(b)); //要把byte数组打印出来得转成String
//方式二
File file = new File("D:/test.txt");
InputStream is =new FileInputStream(file); //这是FileInputStream另一种实例化方式
int a;
while((a=is.read())!=-1){ //这是一个个读取,每一次read都是读一个字节
System.out.print((char)a);
}
}
}
注意,如果test.txt里有中文,方式二是会乱码的,因为 is.read() 每一次是读一个字节,但是一个汉字是两个字节(得看本地编码GBK下两个字节,UTF-8下3个字节),它一下只读一个字节就相当于读了半个汉字,那打印出来必定是乱码,哈哈,一个字母是一个字节,所以换成字母打印正常。
2)输出字节流 OutputStream
这个是所有输出字节流的父类。
基本方法:
OutputStream out = new OutputStream(file) / /file是文件名
out.write(int b) 写出一个byte 到流 b 的底八位写出
out.write(byte[] buf) 将buf的一部分写入流中
out.write(byte[] buf, int start, int size) 将buf的一部分写入流中
out.flush() 清理缓存
out.close
package IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileOutputStream_Test {
public static void main(String[] args) throws IOException {
//方式一
InputStream is =new FileInputStream("D:/test.txt");//先从一个文件里读些数据
byte b[] = new byte[is.available()];
is.read(b);
OutputStream os = new FileOutputStream("D:/test1.txt"); //实例化一个输出流,如果文件不存在会自动创建
os.write(b);//直接把一个byte数组写入到文件中
//方式二
InputStream is1 =new FileInputStream("D:/test.txt");
OutputStream os1 = new FileOutputStream("D:/test1.txt");
int a;
while((a=is1.read())!=-1){ //读一个字节,写一个字节
os1.write(a);
}
is.close();
is1.close();
os.close();
os1.close();
}
}</span><span style="color:#0000ff;font-size: 13px;">
</span>
2.字符流
字符流又是 Reader 和 Writer了,顾名思义,它们处理的是字符数据,但是最底层的还是靠字节流实现的,所以Reader每次的 read()读的也是一个字节,只不过它有个转换器:InputStreamReader,他会把Reader读得的字节流转成字符流,这样每次处理的就是一个字符。 所以重头戏还是 InputStreamReader。
1) 字符的处理,一次处理一个字符(unicode编码)
2) 字符的底层仍然是基本的字节流
3) 字符流的基本实现
InputStreamReader 完成byte流解析为char流,按照编码解析
OutputStreamWriter 提供char流到byte流,按照编码处理
4) 字符流的过滤器
是字符读写的功能扩展,极大的方便了文本的读写操作
BufferedReader : readLine() 一次读取一行
PrintWriter : println() 一次打印一行
5)读取一个文本文件
InputStream is = new FileInputStream("test.txt");
Reader in = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(in);
或者
BufferedReader in = new BufferedReader(new FileReader(filename));
1)Reader
下面是例子
package IO;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
public class Reader_Test {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("D:/test.txt");
Reader r = new InputStreamReader(is); //InputStreamReader是一个转换器,把字节流转成字符流
BufferedReader bf = new BufferedReader(r);
int a;
while((a=bf.read())!=-1){
System.out.println((char)a);
}
}
}
其实大部分时候都是用 字节流的,字符流都字节流给转成的。
InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。所以当test.txt中都是字母(一个字节)时,bf.read()会只读到一个字节,当test.txt中是汉字时,会读到两个字节。直接打印汉字。
2)Writer
writer实在没啥好讲的,用的多是是 FileWriter 和 BufferedWriter
package IO;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Writer_Test {
public static void main(String[] args) throws IOException {
Writer fw = new FileWriter("D:/test1.txt");
fw.write("我们"); //可以直接写入内容
fw.flush(); // 字符流采用缓存区,如果没把数据刷到文件里,文件是没有数据的。fw.close()也可以把流刷入文件
}
}
最后总结下流程:
1.实例化流对象 InputStream is = new FileInputStream(“xxxx”);
2.读取 is.read();
3.后续自由操作
4.关闭流 is.close();