Java笔记I/O流
主要内容
java.io.File类的使用---就是计算机操作系统中的文件和文件夹
1.什么是IO流?
I/O即输入input和输出Output的缩写,就是计算机调度把各个存储中的数据写入写出的过程
通过程序把图片放到一个文件夹中,其实就是把图片转换为一个数据集(例如:二进制),把这些数据一点点传输到文件夹,这个传递的过程就类似于水的流动,这样的一整个过程就称为数据流
java中用"流"来抽象表示这么一个写入写出的功能,封装成一个类。放在java.io这个包中
File类 文件流 数据流的读写都是基于文件的操作
file类只能操作文件本身,不能操作文件中的内容;就类似于你有一个本子,你可以任意调整它的位置
却不能改变它里面的内容
FileInputStream/FileOutputStream/FileReader/FileWriter
Buffered缓冲流 数据流的读写都是基于内存的操作
BufferedInputStream/BufferedOutputStream/BuffereadReader/BuffereadWriter
注:IO操作都是有异常的
2.流大致分
-
按照数据单位的不同分为:字节流(8bt),字符流(16bt)。
按照数据流的流向不同分为:输入流和输出流。
按照角色的不同分为:节点流,处理流。
-
按照操作流的数据单位不同,分为字节流和字符流。字节流按一个字节或多个字节数据读写,当传输的资源文件有中文时,就会出现乱码。;字符流按一个字符或多个字符进行读写
1字符 = 2字节; 1字节(byte) = 8位(bit); 一个汉字占两个字节长度。
-
输入流和输出流
按照流传输方向的不同,分为输入流和输出流
-
节点流和处理流
按流的功能不同,分为节点流和处理流。节点流又称低级流,值只能直接连接数据源进行读写操作。处理流又称高级流,指对已经存在的节点流连接、分装,通过封装后的流进行读写操作。处理流不会直接连接数据源
3.我们在使用的时候应该怎么选择呢?比如什么时候用输出流?什么时候用字节流?可以根据下面三步选择适合自己的流:
-
首先自己要知道是选择输入流还是输出流。这就要根据自己的情况决定,如果想从程序写东西到别的地方,那么就选择输入流,反之就选输出流;
-
然后考虑你传输数据时,是每次传一个字节还是两个字节,每次传输一个字节就选字节流,如果存在中文,那肯定就要选字符流了。
-
通过前面两步就可以选出一个合适的节点流了,比如字节输入流 InputStream,如果要在此基础上增强功能,那么就在处理流中选择一个合适的即可
1|1Java IO原理
IO流用来处理设备之间的数据传输
java程序中,对于数据的输入/输出操作以"流(stream)"的方式进行。
java.io包下提供了各种"流"的类和接口,用以获取不同类型的数据,并通过标准的方法输入或输出数据
注意:不论输入还是输出,都是指计算机
输入input:读取外部数据(磁盘、光盘等存储数据)到程序的(内存)中。
输出output:将程序(内存)数据,输出到磁盘、光盘等存储设备中
1|2字节流
I/O流中针对字节的输入和输出提供了字节流。字节流按传输方向分为字节输入流和字节输出流。字节流的顶级父类:InputStream(输入-读)和OutputStream(输出-写)。这两个类都是抽象类,无法实例化。
( =1).字节输入InputStream
常用方法
-
int read():从输入流中读取一个字节的二进制数据。
-
int read(byte[] b):将多个字节读到数组中,填满整个数组。
-
int read(byte[] b, int off, int len):从输入流中读取长度为 len 的数据,从数组 b 中下标为 off 的位置开始放置读入的数据,读完返回读取的字节数。
-
void close():关闭数据流。
-
int available():返回目前可以从数据流中读取的字节数(但实际的读操作所读得的字节数可能大于该返回值)。
-
long skip(long l):跳过数据流中指定数量的字节不读取,返回值表示实际跳过的字节数。
对数据流中字节的读取通常是按从头到尾顺序进行的,如果需要以反方向读取,则需要使用回推(Push Back)操作。在支持回推操作的数据流中经常用到如下几个方法:
-
boolean markSupported():用于测试数据流是否支持回推操作,当一个数据流支持 mark() 和 reset() 方法时,返回 true,否则返回 false。
-
void mark(int readlimit):用于标记数据流的当前位置,并划出一个缓冲区,其大小至少为指定参数的大小。
-
void reset():将输入流重新定位到对此流最后调用 mark() 方法时的位置。
字节输入流有很多子类,经常使用的一些类见下
-
ByteArrayInputStream:字节数组输入流,该类的功能就是从字节数组 byte[] 中进行以字节为单位的读取,也就是将资源文件都以字节形式存入到该类中的字节数组中去,我们拿数据也是从这个字节数组中拿。
-
PipedInputStream:管道字节输入流,它和 PipedOutputStream 一起使用,能实现多线程间的管道通信。
-
FilterInputStream:装饰者模式中充当装饰者的角色,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类。
-
BufferedInputStream:缓冲流,对处理流进行装饰、增强,内部会有一个缓冲区,用来存放字节,每次都是将缓冲区存满然后发送,而不是一个字节或两个字节这样发送,效率更高。
-
DataInputStream:数据输入流,用来装饰其他输入流,它允许通过数据流来读写Java基本类型。
-
FileInputStream:文件输入流,通常用于对文件进行读取操作。
-
File:对指定目录的文件进行操作。
-
ObjectInputStream:对象输入流,用来提供对“基本数据或对象”的持久存储。通俗点讲,就是能直接传输Java对象(序列化、反序列化用)。
(2).字节输出流 OutputStream
与字节输入流类似,
-
void write(int i):将字节 i 写入到数据流中,它只输出所读入参数的最低 8 位,该方法是抽象方法,需要在其输出流子类中加以实现,然后才能使用。
-
void write(byte[] b):将数组 b 中的全部 b.length 个字节写入数据流。
-
void write(byte[] b, int off, int len):将数组 b 中从下标 off 开始的 len 个字节写入数据流。元素 b[off] 是此操作写入的第一个字节,b[off + len - 1] 是此操作写入的最后一个字节。
-
void close():关闭输出流。
-
void flush():刷新此输出流并强制写出所有缓冲的输出字节。
1|3字符流
从JDK1.1开始,
同其他程序设计语言使用ASCII字符集不同,Java使用Unicode字符集来表示字符串和字符。ASCII字符集以一个字节(8bit)表示一个字符,可以认为一个字符就是一个字节(byte)。但Java使用的Unicode是一种大字符集,用两个字节(16bit)来表示一个字符,这时字节与字符就不再相同。为了实现与其他程序语言及不同平台的交互,Java提供一种新的数据流处理方案,称作读者(Reader)和写者(Writer)。
(1)字符输入流
Reader是所有的输入字符流的父类,它是一个抽象类
-
CharReader和SringReader是两种基本的介质流,它们分别将Char数组、String中读取数据。
-
PipedReader 是从与其它线程共用的管道中读取数据。
-
BufferedReader很明显是一个装饰器,它和其他子类负责装饰其他Reader对象。
-
FilterReader是所有自定义具体装饰流的父类,其子类PushBackReader对Reader对象进行装饰,会增加一个行号。
-
InputStreamReader是其中最重要的一个,用来在字节输入流和字符输入流之间作为中介,可以将字节输入流转换为字符输入流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。
Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。
(2)字符输出流
Writer是所有的输出字符流的父类,它是一个抽象类。
-
CharWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。
-
PipedWriter 是向与其它线程共用的管道中写入数据。
-
BufferedWriter 是一个装饰器为Writer 提供缓冲功能。
-
PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
-
OutputStreamWriter是其中最重要的一个,用来在字节输出流和字符输出流之间作为中介,可以将字节输出流转换为字符输出流。FileWriter 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将OutputStream转变为Writer 的方法。
Writer 中各个类的用途和使用方法基本和OutputStream 中的类使用一致。
1|43.缓冲流
-
作用:为了提高数据的读写速度,在JAVA API提供了带缓冲功能的流类。
-
根据数据操作单位可以把缓冲流分为:
BufferedInPutStream和BufferedOutPutStream
BufferedReader和BufferedWriter
缓冲流要"套接"在相应的节点流之上,对读和写的数据提供了缓冲功能,提高效率,同时添加了一些新方法。
注:缓冲流是把数据缓冲到内存中
实例
1|54.转换流
转换流提供了在字节和字符流之间 的转换。
Java ApI中提供了两个转换流
InputStreamReader和OutputStreamWrite
转换的作用?
字节流中的数据都是字符时,转换为字符流操作更高效。
构造方法:
InputStreamReader( InputStream in)
public InputStreamReader(InputStream in,String charsetName)
例如:Reader red=new InputStreamReader(System.in,"编码类型")//参数1是字节流,参数二是编码类型
一些实例
1|65.标准输入输出流
System.in和System.out分别代表了系统标准输入和输出设备
默认输入设备是键盘,输出设备是屏幕
System.in的类型是InputStream
System.out的类型是PrintStream,它是OutputStream的子类FileOutputStram的子类
实例
1|76.数据流
为了方便操作java语言基本的数据类型的数据,可以使用数据流
数据流有两个类
-
用于读取基本类型的:DataInputStream
-
用于写出基本类型的:DataOutputStream
分别"套接"在InputStream和OutputStream节点流上
DataInputStream中的一些方法
char readChar() byte readByte()
double readDouble() float readFloat()
long readLong() int readInt()
String readUTF()
DataOutputStream中的方法,把上方的read改成write就行
实例
1|87.对象流
实现接口时,需要打开IDEA的快捷键
进入setting→inspections→serialization issues→选择图中的选项
然后在上图位置就可实现自动生产id
注意:对象的序列化与反序列化使用的类要严格一致,包名、类名、类结构所有的都要一致,不然就会异常
1|98.随机存储流
RanbdomAccessFile类程序支持"随机访问的方式",程序可以直接跳到任意的地方来读、写
支持只访问文件的部分内容
可以向已存文件后追加内容。
RandomAccessFile对象包含一个记录指针,用来标记当前读到的位置
RandomAccessFile类对象可以自由移动记录指针;
一些方法:long getFilePointer():获取文件记录指针的当前位置
void seek(long pos):将文件记录指针定位到pos位置
实例



浙公网安备 33010602011771号