IO流
概述
IO就是input和output。而流指的就是Java中提供的读写文件操作的类的总称(称呼)。
输入及输出的概念
1、把电脑硬盘上的数据读到程序中,称为输入,即input,进行数据的read操作。
2、从程序往外部设备写数据,称为输出,即output,进行数据的write操作。
3、输入和输出都是相对于程序而言的。
输入流与输出流
流按照数据的传输方向分为:
1、输入流:往程序中读叫输入流。
2、输出流:从程序往外写叫做输出流。
所有输入流都是InputStream类或者Read类的子类:
1、类名以InputStream结尾的类都是InputStream的子类。
2、类名以Reader结尾的类都是Reader类的子类。
所有输出流都是OutputStream类或者Writer类的子类:
1、类名以OutputStream结尾的类都是OutputStream的子类。
2、类名以Writer结尾的类都是Writer类的子类。
字节流与字符流
概述
1、从数据流编码格式上划分为:字节流和字符流。
2、InputStream和OutputStream的子类都是字节流,作用:可以读写二进制文件,主要处理音频、图片、歌曲、字节流处理单元为1个字节。
3、Reader和Writer的子类都是字符流,作用:主要处理字符或字符串,字符流处理单元为2个字节。
4、字节流将读取到的字节数据,去指定的编码表中获取对应的文字。
常用类
1、字节流中的常用类
(1)字节输入流:FileInputStream
(2)字节输出流:FileOutputStream
字节流的常用类使用—代码示例
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Preview2 {
public static void main(String[] args) throws IOException {
//声明输入/输出流为null,便于之后关闭输入输出流的通道
FileInputStream input = null;
FileOutputStream output = null;
try {
//创建输入流的对象
input = new FileInputStream("G:\\Demo2\\FootBall.java");
//创建输出流的对象,没有这个文件时会创建一个,当有这个文件且有内容时,会覆盖旧的内容
output = new FileOutputStream("G:\\football.txt");
/*
* 读写文件
* read() 从文件中读取一个字节,当文件没有内容可读时,返回-1
* writer() 从程序中写入一个字节
*/
int read = 0;
while((read = input.read()) != -1){
output.write(read);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭输入输出流的通道,无论是否有异常都要关闭
if (input != null){
input.close();
}
if (output != null){
output.close();
}
}
}
}
很显然一次一次的读取、写入字节效率过低,因此有下面的高效传输的方法:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Preview3 {
public static void main(String[] args) throws IOException {
//创建输入输出管道
FileInputStream input = new FileInputStream("G:\\java.jpeg");
FileOutputStream output = new FileOutputStream("G:\\num\\java1.jpeg");
/*
* 读写操作
* 使用read(byte[] b) 一次读取b.length个字节存入byte数组传到程序
* 使用writer(byte[] b,int off,int len) b为字节数组,off写入的b数组的起始位置,len为写入的b数组的字节个数
* 定义int length的目的是怕文件大小不足填满数组时,会被默认值替代,在输出流时使文件变大
*/
byte [] b = new byte[1024];
int length = 0;//存入数组中的实际元素个数
while((length = input.read(b)) != -1){
//读出的字节存放到byte数组b中
output.write(b,0,length);
}
input.close();
output.close();
}
}
2、字符流中的常用类
(1)字符输出流:FileReader
(2)字符输出流:FileWriter
(3)只能用作操作纯文本文件。
(4)关于字符流的常用类之间的关系如图所示
字符流的常用类使用—代码示例
public class IOZFDemo {
/*这是一个程序入口*/
public static void main(String[] args) throws IOException {
FileReader read = null;
FileWriter writer = null;
try {
read = new FileReader("G:\\1.txt");
writer = new FileWriter("G:\\Demo1\\1.txt");
//定义一个接收字符编码的整数
int num = 0;
while ((num = read.read()) != -1) {
System.out.println(num);//可以让你看到每次得到的编码
writer.write(num);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("地址不存在");
} finally {
read.close();
writer.close();
}
}
}
同样的,和字节流一样,字符流也可以使用数组提升效率
public class IOZFDemo1 {
/*这是一个程序入口*/
public static void main(String[] args) throws IOException {
FileReader read = null;
FileWriter writer = null;
try {
read = new FileReader("G:\\1.txt");
writer = new FileWriter("G:\\Demo1\\2.txt");
int length = 0;
char [] chars = new char[1024];
while ((length = read.read(chars)) != -1) {
System.out.println(length);//可以让你看到每次得到的编码
writer.write(chars,0,length);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("地址不存在");
} finally {
read.close();
writer.close();
}
}
}
节点流与处理流
概述
1、根据封装类型的不同,我们将流分为:节点流和处理流。
2、节点流:如果流封装的某种特定的数据源,如文件、字符串、字符串数组等,我们称其为节点流,即我们上面字节流和字符流所举的例子都是节点流。
3、处理流:如果流封装的是其它流对象,我们则称其为处理流,处理流提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。
4、常用类
节点流 | 处理流 |
---|---|
字节输入流 FileInputStream | 缓冲字节输入流 BufferedInputStream |
字节输出流 FileOutputStream | 缓冲字节输出流 BufferedOutputStream |
字符输入流 FileReader | 缓冲字符输入流 BufferedReader |
字符输出流 FileWriter | 缓冲字符输出流 BufferedWriter |
5、在字节流和字符流的基础上我们再使用一张图描绘节点流和处理流的关系
处理流
1、字节流的处理流-----代码示例
public class IOCLDemo1 {
/*这是一个程序入口*/
public static void main(String[] args) throws Exception{
//我们在这里直接抛出一个大异常,精简代码
FileInputStream in = new FileInputStream("G:\\2.mp4");
//处理流---封装的是一个流对象
BufferedInputStream input = new BufferedInputStream(in);
FileOutputStream out = new FileOutputStream("G:\\Demo1\\2.mp4");
BufferedOutputStream output = new BufferedOutputStream(out);
//读写
int length = 0;
byte [] bytes = new byte[1024];
while ((length = input.read(bytes)) != -1) {
output.write(bytes, 0, length);
}
//关流
input.close();
output.flush();//刷新缓冲输出流,确保缓冲区内容输出完毕
output.close();
}
}
2、字符流的处理流-----代码示例
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class IOCLDemo3 {
/*这是一个程序入口*/
public static void main(String[] args) throws Exception{
FileReader read = new FileReader("G:\\1.txt");
BufferedReader reader = new BufferedReader(read);
FileWriter write = new FileWriter("G:\\Demo1\\1.txt");
BufferedWriter writer = new BufferedWriter(write);
//读写
int length = 0;
char[] chars = new char[1024];
while ((length = reader.read(chars)) != -1) {
writer.write(chars);
}
reader.close();
writer.flush();
writer.close();
}
}
public class IOCLDemo2 {
/*这是一个程序入口*/
public static void main(String[] args) throws Exception{
FileReader read = new FileReader("G:\\1.txt");
BufferedReader reader = new BufferedReader(read);
FileWriter write = new FileWriter("G:\\Demo1\\1.txt",true);//true允许写入文档往之前的文档后加
BufferedWriter writer = new BufferedWriter(write);
//读写
String str = null;
while ((str = reader.readLine()) != null) {
//readLine() 读取一行
writer.write(str);//write(String),没有分行的写出
writer.newLine();//写出一行行的分割符
}
reader.close();
writer.flush();
writer.close();
}
}