IO指的是Input/Output,IO流:输入输出流。 统称为数据流。(IO Stream)
在Java程序中,对于数据的输入 / 输出操作以流的方式进行;流是从起源到接收的有序数据。JDK提供了各种各样的流类,用以获取不同种类的数据;
IO流的分类:
按流向分:
◦ 输入流:程序可以从中读取数据的流
◦ 输出流:程序能向其中写入数据的流
按数据传输单位分:
◦ 字节流:以字节为单位传输数据的流
◦ 字符流:以字符为单位传输数据的流
按功能分:
◦ 节点流:用于直接操作目标设备的流
◦ 处理流:是对一个已存在的流的连接和封装,通过对数据的处理为程序提供更强大、灵活的读写功能。
IO流的基类
分类 字节输出流 字节输入流 字符输出流 字符输入流 抽象基类 OutputStream InputStream Writer Reader 访问文件 FileOutputStream FileInputStream FileWriter FileReader 访问数组 ByteArrayOutputStream ByteArrayInputStream CharArrayWriter CharArrayReader 访问管道 PipedOutputStream PipedInputStream PipedWriter PipedReader 访问字符串 StringWriter StringReader 缓冲流 BufferedOutputStream BufferedInputStream BufferedWriter BufferedReader 转换流 OutputStreamWriter InputStreamReader 对象流 ObjectOutputStream ObjectInputStream 抽象基类 FilterOutputStream FilterInputStream FilterWriter FilterReader 打印流 PrintStream PrintWriter 推回输入流 PushbackInputStream PushbackReader 特殊流 DataOutputStream DataInputStream
继承自InputStream的流都是用于向程序中输入数据的,且数据的单位为字节(8位)
java.io.InputStream:字节输入流
此抽象类是表示字节输入流的所有类的超类
定义了所有子类共性的方法
int read()从输入流中读取数据的下一个字节。
int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
void close() 关闭此输入流并释放与该流关联的所有系统资源。
1.1 FileInputStream:文件字节输入流
package com.IOAndProperties.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
/*
java.io.InputStream:字节输入流
此抽象类是表示字节输入流的所有类的超类
定义了所有子类共性的方法
int read()从输入流中读取数据的下一个字节。
int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
void close() 关闭此输入流并释放与该流关联的所有系统资源。
java.io.FileInputStream extends InputStream
FileInputStream:文件字节输入流
作用:把硬盘文件中的数据,读取到内存中使用
构造方法:
FileInputStream(String name)
FileInputStream(File file)
参数:读取文件的数据源
String name:文件的路径
File file:文件
构造方法的作用:
1.会创建一个FileInputStream对象
2.会把FileInputStream对象指定构造方法中要读取的文件
读取数据的原理(硬盘-->内存)
java程序-->JVM-->OS-->OS读取数据的方法-->读取文件
字节输入流的使用步骤(重点)
1.创建FileInputStream对象,构造方法中绑定要读取的数据源
2.使用FileInputStream对象中的方法read,读取文件
3.释放资源
*/
public class Demo01InputStream {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("基础语法\\a.txt");
//2.使用FileInputStream对象中的方法read,读取文件
//int read()读取文件中的一个字节并返回,读取到文件的末尾返回-1
/* int len = fis.read();
System.out.println(len); //97 a
len = fis.read();
System.out.println(len); //98 b
len = fis.read();
System.out.println(len); //99 c
len = fis.read();
System.out.println(len); //-1
len = fis.read();
System.out.println(len); //-1*/
/*
发现以上读取文件是一个重复的过程,所以可以使用循环优化
不知道文件中有多少字节,使用while循环
while循环结束条件,读取到-1的时候结束
布尔表达式(len = fis.read())!= -1;
1.fis.read():读取一个字节
2.len = fis.read():把读取到的字节赋值给变量len
3.(len = fis.read())!= -1:判断变量len是否不等于-1
*/
int len = 0;//读取一个字节
while ((len = fis.read())!=-1){
System.out.print((char)len); //abc
}
//3.释放资源
fis.close();
}
}
1.2 字节输入流读取多个字节
package com.IOAndProperties.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
/*
字节输入流一次读取多个字节的方法
int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
明确两件事情:
1.方法的参数byte[]的作用?
起到缓冲作用,存储每次读取到的多个字节
数组的长度一般定义为1024(1kb)或者1024的整数倍
2.方法的返回值int是什么?
每次读取的有效字节个数
String类的构造方法
String(byte[] bytes):把字节数组转换为字符串
String(byte[] bytes,int offset,int length)把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数
*/
public class Demo02InputStream {
public static void main(String[] args) throws IOException {
//创建FileInputStream对象,构造方法中绑定要读取的数据源
FileInputStream fis = new FileInputStream("基础语法\\b.txt");
//使用FileInputStream对象中的read方法读取文件
//int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。
/* byte[] bytes = new byte[2];
int len = fis.read(bytes);
System.out.println(len); // 2
// System.out.println(Arrays.toString(bytes)); //[65, 66]
System.out.println(new String(bytes)); //AB
len = fis.read(bytes);
System.out.println(len); // 2
System.out.println(new String(bytes)); //CD
len = fis.read(bytes);
System.out.println(len); // 1
System.out.println(new String(bytes)); //ED
len = fis.read(bytes);
System.out.println(len); // -1
System.out.println(new String(bytes)); //ED*/
/*
发现以上读取是一个重复的过程,可以使用循环优化
不知道文件有多少字节,所以使用while循环
while循环结束的条件,读取到-1结束
*/
byte[] bytes = new byte[1024];
int len = 0; //记录每次读取的有效字节个数
while ((len = fis.read(bytes)) != -1){
//String (byte[] bytes,int offset,int length)把把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数
System.out.println(new String(bytes,0,len));
}
// 释放资源
fis.close();
}
}
1.3 OutputStream字节输出流
OutputStream有很多子类,其中子类FileOutputStream可用来写入数据到文件。
FileOutputStream类,即文件输出流,是用于将数据写入 File
的输出流。
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//需求:将数据写入到文件中。
//创建存储数据的文件。
File file = new File("c:\\file.txt");
//创建一个用于操作文件的字节输出流对象。一创建就必须明确数据存储目的地。
//输出流目的是文件,会自动创建。如果文件存在,则覆盖。
FileOutputStream fos = new FileOutputStream(file);
//调用父类中的write方法。
byte[] data = "abcde".getBytes();
fos.write(data);
//关闭流资源。
fos.close();
}
}
继承自Reader的流都是用于向程序中输入数据的,且数据的单位为字符(16位)
Reader字符输入流
Writer字符输出流
继承Writer的流都是向程序中输出数据,且数据的单位为字符(16 bit);
文本文件用Reader,Writer比较方便快速,并且存入的文件默认不会乱码。
public class Demo18 {
public static void main(String[] args) throws IOException {
FileReader in = new FileReader("文件地址");
FileWriter out = new FileWriter("需要复制的到的地址");
//2、FileReader 字符读取
//2、FileReader 字符读取
// int c = -1;
// while ((c = in.read()) != -1) {
// //3、FileWriter 字符写入
// out.write(c);
//
char [] chs = new char[1024];
int len = -1;
while((len=in.read(chs))!=-1){
out.write(chs,0,len);
}
System.out.println("复制成功!");
}
}
注;非文本文件无法复制非文本文件,会导致文件损坏。
实现文件复制(使用字节流):
package cn.sz.gl.test05;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Test {
public static void copyFileByStream(File source, File target) {
// 判断源文件是否存在,如果不存在,就退出程序
if (!source.exists()) {
System.out.println("源文件不存在,程序退出");
System.exit(0);
}
// target.getParentFile()表示用来获取目标对象的父目录对象
// 如果目标文件路径不存在,就创建
if (!target.getParentFile().exists()) {
target.getParentFile().mkdirs();
}
InputStream is = null;
OutputStream os = null;
try {
// 准备输入流
is = new FileInputStream(source);
// 准备输出流
os = new FileOutputStream(target);
// 准备一个数组,用来存放读写的数据
byte[] b = new byte[1024];
int len = 0;
// read(b)实现读取操作,数据存入b数组,返回读取长度给len,当所有内容都读取完毕,len=-1
while ((len = is.read(b)) != -1) {
// 实现写的操作
os.write(b, 0, len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
File source = new File("D:\\java\\Java高级\\myfile\\a.txt");
File target = new File("D:\\java\\Java高级\\myfile\\b.txt");
copyFileByStream(source, target);
}
}
实现文件复制(通过字符流)
package cn.sz.gl.test05;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class Test {
public static void copyFileByWriter(File source, File target) {
// 判断源文件是否存在
if (!source.exists()) {
System.out.println("源文件不存在,程序退出");
System.exit(0);
}
// 判断目标文件路径是否存在,不存在就创建
if (!(target.getParentFile().exists())) {
target.getParentFile().mkdirs();
}
Reader reader = null;
Writer writer = null;
try {
reader = new FileReader(source);
writer = new FileWriter(target);
char c[] = new char[1024];
int len = 0;
while ((len = reader.read(c)) != -1) {
writer.write(c, 0, len);
}
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 多个资源需要关闭时,原则上应该是先开的后关
if (writer != null) {
writer.close();
}
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
File source = new File(
"D:\\java\\Java高级\\myfile\\a.txt");
File target = new File(
"D:\\java\\Java高级\\myfile\\b.txt");
copyFileByWriter(source, target);
}
}