一、概述
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。既数据在两个设备之间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
二、IO流的作用
实现两个对象设备之间的数据传递。
三、IO流的使用场景
- 当我们使用File类时只能实现对文件的操作,包括:获取文件属性,创建、删除,移动文件等等,但不能对文件的内容做出改动。如果想对文件内容操作的话,需要读取,删除文件内容等
- IO流的使用场景:需要对一个文件内容进行操作的时候。
IO流的操作对象是一个文件,而不是对一个文件夹进行读写的。 在使用IO流的时候注意不要与一个文件夹建立连接
四、IO流的分类
按照不同的分类标准分为不同的IO流:
4.1 传输数据的单位分:
- 字节流: 传输的是字节,是以字节为单位的,字节流读取的最小单位是一个字节(1byte=8bit)。 可以操作任意类型的数据。
- 字符流: 传输的是字节,一次可以读取一个字符(1char = 2byte = 16bit), 不同点是在传输过程中加入了编码的操作,让我们的操作更方便文本。
4.2 数据传输的方向分:
- **输入流input:**读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
- **输出流output:**将程序(内存)数据输出到磁盘、光盘等存储设备中
4.3 流的角色的不同分:
- 节点流: 直接从一个源读写数据的流(这个流没有经过包装和修饰),处理流是在对节点流封装的基础上的一种流。FileInputStream是一个节点流,可以直接从文件读取数据,但是BufferedInputStream可以包装 FileInputStream,使得其有缓冲功能。
- 处理流: 它用于对一个已存在的节点流进行连接和封装,通过封装后的流来实现流的读写能力。当使用处理流时,程序不会直接连接到实际的数据源,而是连接在已存在的流之上
五、IO流体系
分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
抽象基类 | InputStream | OutputStream | Reader | Writer |
访问文件 | FileInputStream | FileOutputStream | FileReader | OutWriter |
访问数组 | ByteArrayInputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipeWriter |
访问字符串 | InputStreamReader | OutputStreamWriter | ||
缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputSteamReader | ||
对象流 | ObjectInputStream | ObjectOutputStream | ||
FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
打印流 | PrintStream | PrintWriter | ||
推回输入流 | PushbackInputStream | PushbackReader | ||
特殊流 | DataInputStream | DataOutputStream |
六、字节输入流InputStream
InputStream是一个虚拟类,在Java中是字符输入流,用来将文件中的数据读取到java程序中。
最常用的方法是:FileInputStream
- 常用方法
- int read():从文件中读取一个字节数的数据。并返回读取到的这个字节。如果读取结束,返回是-1;
- int read(byte[] b):一次读取一个字节数组,输入流会把读到的内容放入到这个字节数组中,并返回读取到的一个数,如果读取结束返回-1;
- void close();关闭字节流;
- FileInputStream实现步骤
- 创建一个FileInputStream流对象,绑定一个数据源文件
- 调用read方法读取数据
- 释放资源
- 示例代码
public void inputStreamMethod() throws Exception { FileInputStream in=new FileInputStream("D:\\goyeer.txt"); //创建Fileinptstream 流对象,并绑定源文件 byte[] buf=new byte[1024]; int len; //调用read方法读取数据 while((len=in.read(buf))!= -1){ String line=new String(buf,0,len,"UTF-8"); System.out.println(line); } }
- InputStream体系
七、字节输出流 OutputStream
OutputStream类是Java IO API中所有输出流的基类。子类包括BufferedOutputStream,FileOutputStream等等。OutputStream是一个典型的装饰模式,使用时候直接new子类。OutputStream可以输出console,文件、磁盘等目标媒介中。
- 常用方法
- void close(); 关闭输出流防止资源被大量占用,最终导致超出句柄或内存溢出。
- void write(int b);抽象类中唯一的抽象方法。非抽象子类必须实现这个方法。
- void write(byte b[])直接输出一个字节数组中的全部内容。
- void write(byte b[], int off, int len) 要输出的内容已存储在了字节数组b[]中,但并非全部输出,只输出从数组off位置开始的len个字节。
- void lush()刷空输出流,并输出所有被缓存的字节。由于某些流支持缓存功能,该方法将把缓存中所有内容强制输出到流中。
- OutputStream实现步骤
- 创建一个OutputStream流对象
- write方法输入
- close关闭流防止内存有溢出
- 示例代码
public void outputStreamMethod() throws IOException{ OutputStream ou=new FileOutputStream("D:\\ShowCoding.txt"); String str = "欢迎Goyeer社区"; byte[] bytes = str.getBytes(); for(int i = 0; i < bytes.length; i++) { ou.write(bytes[i]); } ou.close(); }
- OutputStream体系
八、字符输入流Reader
Reader是输入字符流的父类,它是一个抽象类,在文件读写是不推荐使用
- 常用方法
- void close();关闭流并释放与之关联的所有资源;
- void mark(int readAheadLimit);标记流中的当前位置;
- boolean markSupported();判断此流是否支持mark()操作;
- int read();读取单个字符;
- int read(char[] cbuf); 将字符读入数组;
- int read(char[] cbuf, int off, int len);将字符读入数组的某一部分;
- int read(CharBuffer target) ;试图将字符读入指定的字符缓冲区
- boolean ready() ;判断是否准备读取此流;
- void reset();重置该流
- long skip(long n);跳过字符
- Reader实现步骤
- 创建一个文件读取流对象与指定名称的文件相关联起来;保证文件已存在。当文件不存在时,会发生异常(FileNotFoundException);
- 调用读取流对象的read方法,一次读取一个字符,自动往后读取字符;
- 调用方法,关闭字符流;
- 示例代码
public static void readerMethod() throws IOException{ Reader reader=new FileReader("D:\\goyeer.txt"); int ch = 0; char [] buf= new char[1024]; while((ch=reader.read(buf))!=-1){ System.out.print(new String(buf,0,ch)); } reader.close(); }
- Reader体系
九、字符输出流程Writer
Writer类是Java IO中所有Writer的基类,它位于java.io包下面的一个抽象类。实现Writer的实现子类,包含BufferedWriter和PrintWriter.
- 常用方法
- Writer append(char c) 将指定字符添加到此 write
- Writer append(CharSequence csq) 将指定字符序列添加到此 writer
- Writer append(CharSequence csq, int start, int end) 将指定字符序列的子序列添加到此 writer.Appendable
- abstract void close() 关闭此流,但要先刷新它
- abstract void flush() 刷新该流的缓冲
- void write(char[] cbuf) 写入字符数组
- abstract void write(char[] cbuf, int off, int len) 写入字符数组的某一部分
- void write(int c) 写入单个字符
- void write(String str) 写入字符串
- void write(String str, int off, int len) 写入字符串的某一部分
- Writer实现步骤
- 通过子类实例化Writer
- 通过write方法实现文件写入操作
- close关闭输出流,释放资源。
- 示例代码
public static void writeMethod() throws IOException { Writer out = new FileWriter("D:\\goyeer.log"); String str = "I/O字符流,Writer类应用。"; out.write(str); out.close(); }
- Writer体系
十、总结
Java IO既Java输入输出系统,即in和out,指应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络连接。在编写程序时选择适合自己场景的字节流和字符流,及abstract的子类灵活使用。