1.流
1.1 流的概念
流:在 Java中所有数据都是使用流读写的。流是一组有顺序的,有起点和终点的字节集合,是对数据传 输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象 为各种类,方便更直观的进行数据操作。
分类
1.按照流向分:输入流;输出流
2.按照处理数据的单位分:字节流(8位的字节);字符流(16位的字节)
1.2 输入输出流
输入就是将数据从各种输入设备(包括文件、键盘等)中读取到内存中。
输出则正好相反,是将数据写入到各种输出设备(比如文件、显示器、磁盘等)。
文件既可以作为输入设备,又可以作为输出设备。
1.3 Java中IO流
File类不支持文件内容处理,如果要处理文件内容,必须要通过流的操作模式来完成。
在java.io包中,流分为两种:字节流与字符流
字节流:数据流中最小的数据单元是字节 。InputStream、OutputStream
字符流:数据流中最小的数据单元是字符, Java中的字符是Unicode编码,一个字符占用两个字节 。Reader、Writer
Java IO类图
2.字节流
1、 FileInputStream 和 FileOutputStream
方法 | 解释 |
---|---|
FileInputStream(File file) | 通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File 对象 file 命名 |
FileInputStream(String name) | 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name 命名。 |
FileOutputStream(File file) | 创建文件输出流以写入由指定的 File 对象表示的文件。 |
FileOutputStream(String name) | 创建文件输出流以指定的名称写入文件 |
使用 FileInputStream 和 FileOutputStream 复制图片
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream fin=new FileInputStream("E:\\bit\\bit.jpg");
FileOutputStream fout=new FileOutputStream("E:\\bit\\bit\\BitCopy.jpg");
int len=0;
byte[] buff=new byte[1024];
while((len=fin.read(buff))!=-1) {
fout.write(buff, 0, len);
}
fin.close();
fout.close();
}
}
2 字节缓冲流 BufferedInputStream 和 BufferedOutputStream
当我们用read()读取文件时,每读一个字节,访问一次硬盘,效率很低 。文件过大时,操作起来也不是很方便。因此我们需要用到buffer缓存流,当创建buffer对象时,会创建一个缓冲区数组。当我们读一个文件时,先从硬盘中读到缓冲区,然后直接从缓冲区输出即可,效率会更高
方法 | 解释 |
---|---|
BufferedInputStream(InputStream in) | 创建一个 BufferedInputStream 并保存其参数,输入流 in ,供以后使用。 |
BufferedInputStream(InputStream in,int size) | 创建 BufferedInputStream 具有指定缓冲区大小,并保存其参数,输入流in,供以后使用) |
BufferedOutputStream(OutputStream out) | 创建一个新的缓冲输出流,以将数据写入指定 的底层输出流。 |
BufferedOutputStream(OutputStream out, int size) | 创建一个新的缓冲输出流,以便以指定的缓冲 区大小将数据写入指定的底层输出流。 |
使用BufferedInputStream 和 BufferedOutputStream 实现文件拷贝
import java.io.*;
public class TestBufferStreamCopy {
public static void main(String[] args) throws IOException {
File file=new File("bit.txt");
if(!file.isFile()){
return;
}
BufferedInputStream bfis=new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bfos=new BufferedOutputStream(new FileOutputStream("src\\"+file.getName()));//copy到src目录下
byte bytes[]=new byte[1024];
int temp=0; //边读边写
while ((temp=bfis.read(bytes))!=-1){//读
bfos.write(bytes,0,temp); //写
}
bfos.flush();
bfos.close();
bfis.close();
System.out.println("copy成功!");
}
}
3.字符流
1.字符流 FileReader 和 FileWriter
方法 | 解释 |
---|---|
FileReader(File file) | 创建一个新的 FileReader ,给出 File 读取。 |
FileReader(String fileName) | 创建一个新的 FileReader ,给定要读取的文件的名称 |
FileWriter(File file) | 给一个File对象构造一个FileWriter对象。 |
FileWriter(String fileName) | 构造一个给定文件名的FileWriter对象。 |
使用 FileReader 和 FileWriter 复制文件
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//创建输入流对象
FileReader fr = new FileReader("E:\\bit\\bitSrc.java");
//创建输出流对象
FileWriter fw = new FileWriter("E:\\bit\\bitCopy.java");
//读写数据
int ch;
while((ch=fr.read())!=-1) {
fw.write(ch);
}
//释放资源
fw.close();
fr.close();
}
2 字符缓冲流 BuffererdReader 和 BufferedWriter
为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写,提高了单个字符读写的效率。 BufferedReader 用于加快读取字符的速度, BufferedWriter 用于加快写入的速度。
方法 | 解释 |
---|---|
BufferedReader(Reader in) | 创建使用默认大小的输入缓冲区的缓冲字符输入 流。 |
BufferedReader(Reader in, int sz) | 创建使用指定大小的输入缓冲区的缓冲字符输入 流。 |
BufferedWriter(Writer out) | 创建使用默认大小的输出缓冲区的缓冲字符输出流。 |
BufferedWriter(Writer out, int | sz) |
使用 BufferedReader 和 BufferedWriter 进行文件拷贝
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileWrite {
public static void main(String[] args) throws IOException {
FileReader reader=new FileReader("E:\\BIT\\bit.txt");
BufferedReader bReader=new BufferedReader(reader);
FileWriter writer=new FileWriter(":\\BIT\\bit2.txt");
BufferedWriter bWriter=new BufferedWriter(writer);
String content="";
//readLine一行一行的读取
while((content=bReader.readLine())!=null){
//\r\n换行
bWriter.write(content+"\r\n");
}
/**
* 关闭流的顺序:
* 当A依赖B的时候先关闭A,再关闭B
* 带缓冲的流后关闭的时候会执行一次flush
*/
reader.close();
bReader.close();
bWriter.close();
writer.close();
}
}
4. 字节流对比字符流
1、字节流操作的基本单元是字节;字符流操作的基本单元为Unicode码元。
2、字节流在操作的时候本身不会用到缓冲区的,是与文件本身直接操作的;而字符流在操作的时候使 用到缓冲区的。
3、所有文件的存储都是字节(byte)的存储,在磁盘上保留的是字节。
4、在使用字节流操作中,即使没有关闭资源(close方法),也能输出;而字符流不使用close方法的 话,不会输出任何内容
5. 字符字节转换流
有时候我们需要进行字节流与字符流二者之间的转换,因为这是两种不同的流,所以,在进行转换的时 候我们需要用到 OutputStreamWriter 和 InputStreamReader
InputStreamReader 是Reader的子类,将输入的字节流转换成字符流。
方法 | 解释 |
---|---|
InputStreamReader(InputStream in) | 创建一个使用默认字符集的 InputStreamReader。 |
InputStreamReader(InputStream in,Charset cs) | 创建一个使用给定字符集的 InputStreamReader |
public class TestDemo {
public static void main(String[] args) {
// 创建字节流对象 System.in 代表从控制台输入
InputStream in = System.in;
// 创建字符流对象
BufferedWriter bw = null;
BufferedReader br = null;
try {
// 实例化字符流对象 通过 InputStreamReader 将字节输入流转化成字符输入流
br = new BufferedReader(new InputStreamReader(in));
//br = new BufferedReader(new InputStreamReader(in,"GBK"));
bw = new BufferedWriter(new FileWriter("a.txt")); // 定义读取数据的行
String line = null;
// 读取数据
while ((line = br.readLine()) != null) {
// 如果输入的是"exit"就退出
if("exit".equals(line)){
break;
}
// 将数据写入文件
bw.write(line);
// 写入新的一行
bw.newLine();
// 刷新数据缓冲
bw.flush();
}
} catch (Exception e){
e.printStackTrace();
} finally {
// 释放资源
try {
if(bw != null)
bw.close();
if (br != null)
br.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
OutputStreamWriter 是Writer的子类,将输出的字符流转换成字节流。
方法 | 解释 |
---|---|
OutputStreamWriter(OutputStream out) | 创建一个使用默认字符编码的OutputStreamWriter。 |
OutputStreamWriter(OutputStream out,Charset cs) | 创建一个使用给定字符集的 OutputStreamWriter。 |
public class TestDemo {
public static void main(String[] args) {
// 定义字节输出流的对象System.out
OutputStream out = System.out;
// 定义字符流的对象
BufferedReader br = null;
BufferedWriter bw = null;
try {
//通过OutputStreamWriter将字符转流换为字节流对象
bw = new BufferedWriter(new OutputStreamWriter(out));
//bw = new BufferedWriter(new OutputStreamWriter(out,"GBK"));
br = new BufferedReader(new FileReader("a.txt")); // 定义读取行的字符串
String line = null;
// 读取数据
while ((line = br.readLine()) != null) {
// 输出到控制台
bw.write(line);
// 新的一行
bw.newLine();
// 刷新缓冲
bw.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放资源
try {
if (bw != null)
bw.close();
if (br != null)
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}