流的概念和作用
- 是一组有顺序,有起点和终点的字节集合。
- 流也是对数据传输的总称,即在两个设备之间进行数据传输被称为流,流的本质是数据传输。
流的分类
- 根据处理数据类型可以分为:字符流和字节流。
- 根据数据流向可以分为:输入流和输出流。
字符流和字节流
字符流,本质就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:
- 读写单位:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可以读多个字节。
-
处理对象:字节流可以处理所有类型的数据(如图片、avi等),字符流只能处理字符类型的数据。
- 字节流:一次读入或读出8位二进制。
-
字符流:一次读入或读出16位二进制。
建议:只要是处理纯文本数据,优先考虑使用字符流。
输入字节流 InputStream
InputStream
是所有的输入字节流的父类,它是一个抽象类。ByteArrayInputStream
、StringBufferInputStream
、FileInputStream
是三种基本的介质流,它们分别从Byte 数组
、字符串
、和本地文件
中读取数据。PipedInputStream
是从与其它线程共用的管道中读取数据。ObjectInputStream
和所有FilterInputStream
的子类都是装饰流。
输出字节流 OutputStream
OutputStream
是所有的输出字节流的父类,它是一个抽象类。ByteArrayOutputStream
、FileOutputStream
是两种基本的介质流,它们分别向Byte 数组
、和本地文件
中写入数据。PipedOutputStream
是向与其它线程共用的管道中写入数据。ObjectOutputStream
和所有FilterOutputStream
的子类都是装饰流。
节点流
直接与数据源相连,读入或读出。
常用的节点流
- 父 类 :
InputStream
、OutputStream
、Reader
、Writer
- 文 件 :
FileInputStream
、FileOutputStrean
、FileReader
、FileWriter
- 数 组 :
ByteArrayInputStream
、ByteArrayOutputStream
、CharArrayReader
、CharArrayWriter
- 字符串 :
StringReader
、StringWriter
- 管 道 :
PipedInputStream
、PipedOutputStream
、PipedReader
、PipedWriter
处理流
处理流和节点流一块使用,在节点流的基础上,再套接一层,套接在节点流之上的就是处理流。如 BufferedReader
。一个流对象经过其他流的多次包装,称为流的链接。
常用的处理流
- 缓冲流:
BufferedInputStream
、BufferedOutputStream
、BufferedReader
、BufferedWriter
增加缓冲功能,避免频繁读写硬盘。 - 转换流:
InputStreamReader
、OutputStreamReader
实现字节流和字符流之间的转换。 - 数据流:
DataInputStream
、DataOutputStream
将基础数据类型写入到文件中,或者读取出来。
以下是总结的简单示例,经测试通过,有需要的可作参考:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
public class OperateTxt {
public static void main(String[] args) {
try {
// 读TXT文件
String filePath = "D:\\20190222\\123.txt";
File file = new File(filePath);
//begin
//字节流读取文件
InputStream in = new FileInputStream(file);
//缓存字节流读取文件,使用方式和字节流差不多,但是效率更高(推荐使用)
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
//循环取出数据
byte[] bytes = new byte[1024];
int len = -1;
while ((len = in.read(bytes,0,bytes.length)) != -1) {
String str = new String(bytes,0,len,"GBK");
System.out.println(str);
}
in.close();//关闭流
//end
//begin
/*字符流读取文件,和字节流循环取数据不同,这里调用的是in.readLine()方法。*/
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file),"GBK"));
//循环取出数据
String str = null;
while ((str = in.readLine()) != null) {
System.out.println(str);
}
in.close();//关闭流
//end
// 写Txt文件
File file2 = new File("D:\\20190222\\abc\\123.txt");
File fileParent = file2.getParentFile();
if(!fileParent.exists()){
//mkdir() 创建指定的目录,如果父目录不存在则创建不成功。
//mkdirs() 创建指定的目录,包括所有必需但不存在的父目录。
//我这里事先定义了20190222,但是没有定义abc,所以用mkdir。
fileParent.mkdir();
}
file2.createNewFile();// 创建新文件
//字节流写入相应的文件
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file2));
//字符流写入相应的文件
BufferedWriter out = new BufferedWriter(new FileWriter(file2));
//使用了转换流OutputStreamWriter
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file2),"GBK"));
out.write("你好\r\n"); // \r\n 即为换行
out.flush(); // 清楚缓存
out.close(); // 关闭流
} catch (Exception e) {
e.printStackTrace();
}
}
}