IO概述
什么是IO?
java中I/O的操作主要是靠java.io包下的类和接口来实现的。
IO分类
根据数据的流向:输入流和输出流
- 输入流:把数据从其他设备上读取到内存当中的流。
- 输出流:把数据从内存当中写入到其他设备上的流。
根据数据的类型分为:字节流和字符流
- 字节流:以字节为单位,读写数据的流
- 字符流:以字符为单位,读写数据的流
IO流的顶级父类
输入流 | 输出流 | |
---|---|---|
字节流 | InputStream | OutputStream |
字符流 | Reader | Writer |
字节流
一切皆为字节
一切文件数据(文本文档、图片、视频等)在存储时,都是以二进制数字的形式保存的,都是一个个的字节,那么数据在进行传输的时候也是如此。所以字节流可以传输任意文件的数据。在操作流的时候,我们要明确,无论使用了什么样流对象,底层传输始终为二进制。
字节输出流(OutputStream)
java.io.OutputStream此抽象类是表示输出字节流的所有类的超类,将指定的信息写入到目的地。它定义了字节输出流的基本共性的API方法:
- public void close() : 关闭此输出流并释放与此流相关的其他任何系统资源。
- public void flush() : 刷新此输出流并强制任何缓冲的输出字节信息被写入。
- public void write(byte[] b) : 将b.length字节从指定的字节数组写入到此输出流中。
- public void write(byte[] b ,int off,int len) : 从指定的字节数组写入len个字节,从偏移量off开始输出到此输出流中
- public abstract void write(int b) : 将指定的字节输出到此输出流中
备注:close方法,当完成流的操作时,必须调用此方法,释放系统资源。
FileOutputStream类
java.io.FileOutputStream类是文件字节输出流,用于数据写入到文件中
构造方法的作用:
- 创建一个FileOutputStream对象
- 会根据构造方法中传递的文件/文件路径(路径上文件不存在),创建一个空的文件
- 会把FileOutputStream对象指向创建好的文件
字节输出流的使用步骤:
- 创建FileOutputStream对象,构造方法中传递写入数据的目的地。
- 调用FileOutputStream对象中的方法write,把数据写入到文件中。
- 释放资源
- public FileOutputStream(File file) : 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
- FileOutputStream(String name) : 创建一个向具有指定名称的文件中写入数据的输出文件流。
当你创建一个流对象时,必须先传递一个文件路径,该路径下,如果没有这个文件,会创建该文件,如果有这个文件,会清空这个文件当中的数据。
数据的追加续写
- public FileOutputStream(File file,boolean append) : 创建文件输出流以写入由指定的file对象表示的文件中。
- public FileOutputStream(String name,boolean append) : 创建文件输出流以指定的名称写入文件中。
写入换行
Windows系统里,换行符号是\r \n。把一指定是否需要追加续写换行。
Linux系统里,换行符号是/n
mac系统里,换行符号是/r
Unix系统里,每行结尾只有换行,即\n
回车符\r和换行符\n
- 回车符:回到一行的开头
- 换行符:下一行(newLine)
系统中的换行:
- Windows系统中,每行结尾是
回车+换行
。即\r\n
。 - Unix系统中,每行的结尾只有
换行
,即/n
- Mac系统中,每行的结尾是
回车
,即/r
字节输入流(InputStream)
java.io.InputStream此抽象类表示字节输入流的所有类的超类。可以读取字节信息到内存中。它定义了字节输入流的基本共性的API方法:
- public void close() :关闭此输出流并释放与此流相关的其他任何系统资源。
- public abstract int read() :从输入流中读取数据的下一个字节。
- public int read(byte[] b) : 从输入流中读取一些字节数,并将它们存储到字节数组b当中。
FileInputStream类
java.io.FileInputStream类是文件输入流,从文件中读取字节。
构造方法
- FileInputStream(File file):通过打开与实际文件的链接来创建一个FileInputStream,该文件系统中的File对象file命名。
- FileInputStream(String name): 通过打开与实际文件的链接来创建一个FileInputStream,该文件由文件系统中的路径名name命名。
当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有文件,会抛出FileNotFoundException异常。
可以使用字节数组来读取数据:read(byte[] b):从输入流中读取多个字节,并且将其存储到缓冲区数组b当中。当读取到文件的末尾时,返回一个-1
。
代码演示:
//1.创建对象
FileInputStream fis = new FileInputStream("day28_IO\\c.txt");
int len = 0;// 记录读取到的有效字节个数
byte[] bytes = new byte[1024];// 2^10 1024b = 1kb
while ((len = fis.read(bytes)) != -1) {
// byte[] 转换成String
// String(byte[] bytes,int offset,int length) 把字节数组的一部分转换成字符串
//System.out.println(Arrays.toString(bytes));//[B@74a14482
System.out.println(new String(bytes,0,len));
}
备注:使用数组读取,每次可以读取多个字节,减少了系统间的IO操作次数,从而提高了读取的效率,建议使用。
字符流
当使用字节流读取文件的时候,如果有中文可能会出现乱码的情况。所以java提供了
一些字符流类,以字符为单位读写数据,专门用于处理文本文档文件。
字符输入流(Reader)
java.io.Reader 抽象类是表示用于读取字符流的所有超类,可以读取字符信息到内存当中,它的API方法:
- public void close() :
- public int read() : 从输入流中读取一个字符。
- public int read(char[] chuf) : 从输入流中一次读取多个字符,并将它们存储到字符数组chuf当中。
FileReader类
java.io.FileReader 类主要是用于读取字符文件的便捷类。构造方法使用时默认的编码字符集和默认的字节缓冲区。
备注:
- 字符编码:字节与字符的对应规则。Windows系统中中文的默认编码是GBK编码表,idea中采用UTF-8
- 字节缓冲区:一个字节数组,用来临时存储字节数组
构造方法
- FileReader(File file):创建一个新的FileReader对象,指定需要读取的file对象。
- FileReader(String filename):创建一个新的FileReader对象,指定需要读取的文件名称。
字符输出流(Writer)
- void write(int c) : 写入单个字符。
- void write(chat[] chuf): 写入字符数组
- adstract void write(char[] chuf,int off,int len) : 写入char数组的一部分,从char数组的起始索引值off开始,len个写入字符个数。
- void write(String str) : 写入字符串
- void write(String str,int off,int len) : 写入字符串的一部分,从字符串的起始索引off开始,写入len个字符个数。
- void flush() : 刷新该流的缓冲
- void close()
FileWriter类
构造方法
- FileWrite(Ffile file):创建一个新的FileWriter,指定写入的file对象。
- FileWriter(String filename) : 创建一个新的FileWriter,指定需要写入的文件的名称。
关闭和刷新
因为内置缓冲区的原因,如果不关闭输出流,无法写入字符到文件中。但是关闭流对象,是无法继续写入数据到文件中。如果既想写入数据到文件中,又想继续使用流对象,那么就需要flush方法。
- flush: 刷新缓冲区,流对象可以继续使用
- close: 先刷新缓冲区,然后会通知系统释放资源,关闭流对象,流对象不可以再使用。
IO异常处理
/*
JDK7新特性:
在try的后边可以增加一个(),在括号中定义流对象
那么这个流对象的作用域就在try中有效
try中的代码执行完毕,会自动把对象释放,不用写finally
格式:
try(定义流对象) {
// 可能会出现异常的代码
} catch(异常类型 异常变量名) {
// 异常的处理逻辑
}
*/
public class Demo02JDK7Exception {
public static void main(String[] args) {
try(
// 1.1 new
FileOutputStream fw = new FileOutputStream("day28_IO\\2.jpg");
// 1.2 new
FileInputStream fr = new FileInputStream("C:\\Users\\admin\\Desktop\\2.jpg");
) {
// 2. write
int len = 0;
while ((len = fr.read()) != -1) {
fw.write(len);
}
} catch (IOException e) {
// 异常的处理逻辑
e.printStackTrace();
}
}