Java 的IO流按流向分为输入流和输出流,按流的性能,又可以将流分为节点流和处理流
节点流
(直接与数据源相连,读入或读出)
父 类 :InputStream 、OutputStream、 Reader、 Writer
文 件 :FileInputStream 、 FileOutputStrean 、FileReader 、FileWriter 文件进行处理的节点流
数 组 :ByteArrayInputStream、 ByteArrayOutputStream、 CharArrayReader 、CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)
字符串 :StringReader、 StringWriter 对字符串进行处理的节点流
管 道 :PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 对管道进行处理的节点流
处理流
(直接使用节点流,读写不方便,为了更快的读写文件,才有了处理流,在节点流的基础上,再套接一层)
缓冲流:BufferedInputStream 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
转换流:InputStreamReader 、OutputStreamReader实现字节流和字符流之间的转换。
数据流:DataInputStream 、DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。
package com.io.test;
import junit.framework.TestCase;
import java.io.*;
/**
* @author tli2
* @createDate 2022/5/6 15:36
*/
public class IOUtilsTest extends TestCase {
//learn
//https://www.cnblogs.com/fysola/p/6123947.html
//https://www.cnblogs.com/liuzeyu12a/category/1400720.html
//Java 的IO流按流向分为输入流和输出流,按流的性能,又可以将流分为节点流和处理流
//节点流(直接与数据源相连,读入或读出)
// 父 类 :InputStream 、OutputStream、 Reader、 Writer
// 文 件 :FileInputStream 、 FileOutputStrean 、FileReader 、FileWriter 文件进行处理的节点流
// 数 组 :ByteArrayInputStream、 ByteArrayOutputStream、 CharArrayReader 、CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)
// 字符串 :StringReader、 StringWriter 对字符串进行处理的节点流
// 管 道 :PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 对管道进行处理的节点流
//直接使用节点流,读写不方便,为了更快的读写文件,才有了处理流
//处理流(在节点流的基础上,再套接一层)
// 缓冲流:BufferedInputStream 、BufferedOutputStream、 BufferedReader、 BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
// 转换流:InputStreamReader 、OutputStreamReader实现字节流和字符流之间的转换。
// 数据流: DataInputStream 、DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来。
//-----------------------节点流1(文件/字节)
public void testFileInputStream() throws IOException {
FileInputStream fis = new FileInputStream("src/main/resources/test.txt");
byte[] buf = new byte[1024];
int hasRead = 0;
//read()返回的是单个字节数据(字节数据可以直接专程int类型),但是read(buf)返回的是读取到的字节数,真正的数据保存在buf中
while ((hasRead = fis.read(buf)) > 0) {
//每次最多将1024个字节转换成字符串,这里tmp2.txt中的字符小于1024,所以一次就读完了
//循环次数 = 文件字符数 除以 buf长度
System.out.println(new String(buf, 0, hasRead));
/*
* 将字节强制转换成字符后逐个输出,能实现和上面一样的效果。但是如果源文件是中文的话可能会乱码
for (byte b : buf) {
char ch = (char)b;
if (ch != '\r')
System.out.print(ch);
}
*/
}
//在finally块里close更安全
fis.close();
}
public void testFileOutStream() throws IOException {
try (
//在try()中打开文件会在结尾自动关闭
FileInputStream fis = new FileInputStream("src/main/resources/test.txt");
FileOutputStream fos = new FileOutputStream("src/main/resources/out.txt");
) {
byte[] buf = new byte[4];
int hasRead = 0;
while ((hasRead = fis.read(buf)) > 0) {
//每读取一次就写一次,读多少就写多少
fos.write(buf, 0, hasRead);
}
System.out.println("write success");
} catch (IOException e) {
e.printStackTrace();
}
}
//-----------------------节点流2(文件/字符)
public void testFileReader() throws IOException {
try (
// 在try() 中打开的文件, JVM会自动关闭
FileReader fr = new FileReader("src/main/resources/test.txt")) {
char[] buf = new char[32];
int hasRead = 0;
// 每个char都占两个字节,每个字符或者汉字都是占2个字节,因此无论buf长度为多少,总是能读取中文字符长度的整数倍,不会乱码
while ((hasRead = fr.read(buf)) > 0) {
// 如果buf的长度大于文件每行的长度,就可以完整输出每行,否则会断行。
// 循环次数 = 文件字符数 除以 buf长度
System.out.println(new String(buf, 0, hasRead));
// 跟上面效果一样
// System.out.println(buf);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void testFileWriter() throws IOException {
try (FileWriter fw = new FileWriter("src/main/resources/out2.txt")) {
fw.write("天王盖地虎\r\n");
fw.write("宝塔镇河妖\r\n");
} catch (IOException e) {
e.printStackTrace();
}
}
//-----------------------节点流3(字节数组/字节)
public void testByteArrayInputStream(){
//1、创建源
byte[] src = "talk is cheap show me the code".getBytes();
//2、选择流
InputStream is =null;
try {
is =new ByteArrayInputStream(src);
//3、操作 (分段读取)
byte[] flush = new byte[5]; //缓冲容器
int len = -1; //接收长度
while((len=is.read(flush))!=-1) {
//字节数组-->字符串 (解码)
String str = new String(flush,0,len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源
try {
if(null!=is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void testByteArrayOutputStream(){
//1、创建源
byte[] dest =null;
//2、选择流 (新增方法)
ByteArrayOutputStream baos =null;
try {
baos = new ByteArrayOutputStream();
//3、操作(写出)
String msg ="show me the code";
byte[] datas =msg.getBytes(); // 字符串-->字节数组(编码)
baos.write(datas,0,datas.length);
baos.flush();
//获取数据
dest = baos.toByteArray();
System.out.println(dest.length +"-->"+new String(dest,0,baos.size()));
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
//4、释放资源
try {
if (null != baos) {
baos.close();
}
} catch (Exception e) {
}
}
}
//----------------------缓冲流1(文件/字节)
public void testBufferedInputStream(){
File src = new File("src/main/resources/test.txt");
//2、选择流
InputStream is =null;
try {
is =new BufferedInputStream(new FileInputStream(src));
//3、操作 (分段读取)
byte[] flush = new byte[1024]; //缓冲容器
int len = -1; //接收长度
while((len=is.read(flush))!=-1) {
//字节数组-->字符串 (解码)
String str = new String(flush,0,len);
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//4、释放资源
try {
if(null!=is) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void testBufferedOutputStream(){
//1、创建源
File dest = new File("src/main/resources/testBufferedOutputStream.txt");
//2、选择流
OutputStream os =null;
try {
os =new BufferedOutputStream( new FileOutputStream(dest));
//3、操作(写出)
String msg ="IO is so easy\r\n";
byte[] datas =msg.getBytes(); // 字符串-->字节数组(编码)
os.write(datas,0,datas.length);
os.flush();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
//4、释放资源
try {
if (null != os) {
os.close();
}
} catch (Exception e) {
}
}
}
//----------------------缓冲流2(文件/字符)
public void testBufferedReader() throws IOException {
try (
FileInputStream fis = new FileInputStream("src/main/resources/test.txt");
//InputStreamReader是从byte转成char的桥梁
InputStreamReader reader = new InputStreamReader(fis); // 这是一种转换流,字节转字符
//BufferedReader(Reader in)是char类型输入的包装类
BufferedReader br = new BufferedReader(reader);
) {
String line = null;
while ((line = br.readLine()) != null) {
if (line.equals("exit")) {
//System.exit(1);
break;
}
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void testBufferedWriter(){
//1、创建源
File dest = new File("src/main/resources/testBufferedWriter.txt");
//2、选择流
BufferedWriter writer =null;
try {
writer = new BufferedWriter(new FileWriter(dest));
//3、操作(写出)
writer.append("IO is so easy");
writer.newLine();
writer.append("尚学堂欢迎你");
writer.flush();
}catch(FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally{
//4、释放资源
try {
if (null != writer) {
writer.close();
}
} catch (Exception e) {
}
}
}
}