介绍
流就是数据无结构化的传递。强调的是数据的传输过程。
流分为输入流(Input)和输出流(Output),所以简称为I/O流。
输入流表示从一个源读取数据比如从硬盘读入内存,输出流表示向一个目标写数据 比如从内存写入磁盘。
Java中I/O操作主要是指使用java.io
包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。
Java中IO流分类
在JDK中提供了IO类的支持。这些类都在java.io包中。
1. 根据方向的划分: 输入流和输出流
2. 根据数据的单位划分: 字节流和字符流。
3. 根据功能的划分: 节点流和处理流(缓冲流)
字节流就是流中数据以字节为单位(byte)。特别适用于音频、视频、图片等二进制文件的输入、输出操作。
字符流就是流中数据以字符为单位。存在的意义:高效、方便的读取文本数据。此处需要注意的是字符流单位可能是一个字节,可能是多个字节。例如读取英文a,就用一个字符,读取汉字就两个字符
Java中IO流体系图
File类
在JDK中存在一个java.io.File类,这个类是对应的是操作系统中的一个文件或一个文件夹(目录)。
通过File可以实现系统中文件的创建、删除、查看、重命名等操作。
public static void main(String[] args) throws IOException {
File file = new File("E:\\fletest\\aa\\a.txt");
if(file.exists()){
file.delete(); //删除
}else {
File parent = file.getParentFile(); //获得父目录
if(!parent.exists()){
parent.mkdirs(); //创建文件夹
}
file.createNewFile(); //创建新文件
}
}
遍历目录及文件
public static void getFiles(String filename,String s) {
File file2 = new File(filename);
if(!file2.exists()) return;
for (File listFile : file2.listFiles()) {
if(listFile.isDirectory()){
System.out.println(s+listFile.getName());
getFiles(listFile.getAbsolutePath(),s+"-");
}else {
System.out.println(s+"|"+listFile.getName());
}
}
}
getFiles("E:\\test","");
字节输入输出流
传输过程中,传输数据的最基本单位是字节的流。
FileInputStream和FileOutputStream是文件操作常用的两种流。我们可以借助这两个流实现文件读取、文件输出、文件拷贝等功能。
把硬盘上的文件读取到应用程序中使用FileInputStream。
把应用程序中文件内容输出到硬盘上使用FileOutputStream。
注意:
1. 流使用完毕一定要关闭,释放资源。
2. 如果输出流内容来源于输入流,要先关输出流后关输入流。
使用字节输入输出流复制文件 由于读取是字节 可以读取图片 视频音频等
public class InOutTest {
public static void main(String[] args) throws IOException {
// InputStream fileInputStream = new FileInputStream("E:\\fletest\\aa\\a.txt");
// FileOutputStream fileOutputStream = new FileOutputStream("E:\\fletest\\aa\\b.txt");
InputStream fileInputStream = new FileInputStream("E:\\fletest\\aa\\1.png");
FileOutputStream fileOutputStream = new FileOutputStream("E:\\fletest\\aa\\2.png");
// FileOutputStream fileOutputStream = new FileOutputStream("E:\\fletest\\aa\\b.txt",true); //追加
byte[] by = new byte[1024];
int read =0;
while ((read = fileInputStream.read(by))!=-1){
fileOutputStream.write(by,0,read);
}
fileOutputStream.close();
fileInputStream.close();
}
}
字符输入输出流
传输过程中,传输数据的最基本单位是字符的流。
字符编码方式不同,有时候一个字符使用的字节数也不一样,比如ASCLL方式编码的字符,占一个字节;而UTF-8方式编码的字符,一个英文字符需要一个字节,一个中文需要两个字节。
把硬盘上的文件读取到应用程序中使用FileReader。
把应用程序中文件内容输出到硬盘上使用FileWriter。
public class InOutTestB {
public static void main(String[] args) throws IOException {
Reader reader = new FileReader("E:\\fletest\\aa\\a.txt");
// FileWriter writer = new FileWriter("E:\\fletest\\aa\\b.txt");
FileWriter writer = new FileWriter("E:\\fletest\\aa\\b.txt",true); //追加
char[] by = new char[1024];
int read =0;
while ((read = reader.read(by))!=-1){
writer.write(by,0,read);
}
//一个一个读
//while ((read = reader.read())!=-1){
// writer.write(read);
// }
writer.close();
reader.close();
}
}
try-with-source
try-with-source 是java 7引入的。主要是为了解决因为忘记关闭资源而导致的性能问题和调用关闭方法而导致的代码结构乱的问题。
2. 语法
try(需要在finally关闭的资源对象定义,可以写多条代码){
}catch(){
}
public static void main(String[] args) {
try (
//1.创建字符输入流对象
FileReader fileReader = new FileReader("D:/a.txt");
//2.创建字符输出流对象
FileWriter fileWriter = new FileWriter("D:/b.txt");)
{
//3.读取
char[] chars = new char[1024];
int length; //每次读取的长度
while ((length = fileReader.read(chars)) != -1) {
//4.输出
fileWriter.write(chars, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
缓冲流
Java IO中BufferedXXX相关的流统称缓冲流。其本质就是在输入输出时添加缓冲区,减少磁盘IO的次数, 这样可以提高读写效率,同时也可以反复读取。
缓冲流称为上层流(高效流),其底层必须有字节流或字符流。当使用完成后关闭缓冲流,字节流或字符流也会随之关闭。
可以使用flush()刷新(清空)缓冲区内容,把内容输出到目的地。
当缓存区满了以后会自动刷新。在代码中当关闭流时,底层自动调用flush()方法。
字节缓冲流
public class TestCopy5 {
public static void main(String[] args) throws IOException {
//1.创建一个输入流和输出流
InputStream fis = new FileInputStream(new File("e:/JDK_API.CHM"));
OutputStream fos = new FileOutputStream(new File("e:/JDK_API2.CHM"));
//默认输入缓冲区大小8192
BufferedInputStream bis = new BufferedInputStream(fis);
//默认输出缓冲区大小8192
BufferedOutputStream bos = new BufferedOutputStream(fos);
//2.使用输入流和输出流完成文件复制
//2.1准备一个中转站(水杯)
int n;
//2.2先读一个字节
n = bis.read();//读取一个字节,赋给n read操作时 缓冲区没有则从硬盘中加入缓冲区
while(n != -1){
//2.3再写一个字节
bos.write(n);
//2.4在读一个字节
n = bis.read();
}
//3.关闭输入流和输出流
bis.close();
bos.close();
}
}
字符缓冲流
public class InOutBufferTestB {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader("E:\\fletest\\aa\\a.txt"));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("E:\\fletest\\aa\\b.txt",true));
int read = 0;
char[] chars = new char[1024];
//read操作时 缓冲区没有则从硬盘中加入缓冲区
while ((read = bufferedReader.read(chars))!=-1){
bufferedWriter.write(chars);
}
//关闭缓冲区 执行flush();
bufferedReader.close();
bufferedWriter.close();
}
}