JAVA---I/O流
I/O流
我们在做项目时,除了自定义的一些数据外,还可能从"外界"引入数据,或者将数据导出到"外界"。
这时我们需要I/O操作。
外界:指的可能是键盘,显示器,硬盘,另外一个程序流:就是数据序列,一经创建成功,就会打开一个通道。所以使用完应该进行关闭操作。
I/O流的分类
(1)按照流向分类:
输入流
输出流
(2)按照处理的数据单位分类:
字节流-----一般为低级流
字符流-----都是高级流
(3)按照功能分类:
节点流:直接连接两个设备的流类型
处理流:对节点流再次封装与处理的流类型
字节流
字节流各种文件都可以传输
抽象父类:InputStream/OutputStream
InputStream:定义了字节流的常用方法
int available()
void close()
int read():读取一个字节,存入int的低八位上,范围是0—255
int read(byte[] b):读取字节存入字节数组b中,返回的是读取的有效字节个数
int read(byte[] b,int off,int len)
long skip()
OutputStream:定义了字节输出流的常用方法
void close()
void flush();//冲刷,作用是将流里的数据,冲刷进文件中
void write(byte[] bs):写一个字节数组
void write[int b]:写一个字节
void write(byte[] b,int off,int len)
1、文件字节流 FileInputStream/FileOutputStream
继承了字节流的抽象父类。重写了方法,并且提供了自己独有的方法。FileInputStream
构造器:
FileInputStream(File file)-------------创建一个指定路径的File对象的文件输入流对象
FileInputStream(String name)-------创建一个指定路径的字符串的文件输入流对象
常用方法:
int read()-----读取该流中的一个字节数据,即8位二进制,存储到一个int数据的低八位上。
如果返回-1,读至文件末尾。
long skip(long n)------跳过流中n个字节
int read(byte[] b)------读取字节存入byte数组中,最多能读b.length个字节
返回的是实际读取的字节个数
int available()----------查看此输入流中剩余的字节数
FileOutputStream
构造器:
FileOutputStream(File file)
FileOutputStream(File file, boolean append)
FileOutputStream(String name)
FileOutputStream(String name, boolean append)
创建一个指定路径的输出流对象,append表示在文件末尾追加
PS:如果指定路径下的文件名不存在,会自动创建。如果父路径不存在,则报异常FileNotFoundException
常用方法:
void write(int b)-------------写出参数b中的一个字节,int类型的低8位。
void write(byte[] b)---------将字节数组b中的字节按顺序写出
void write(byte[] b,int off,int len)--------将字节数组b中的字节按顺序写出,从下标off,写len个
2、字节缓冲流: BufferedOutputStream/ BufferedOutputStream
BufferedOutputStream:字节缓冲输出流
缓冲输出流的特点是:在流里维护了一个缓冲区,写字节时,先将字节写入缓冲区,当缓冲区满时,再一次性的将数据写到文件里。这样就降低了写的次数,因此提高了效率。
因为缓冲输出流缺失即时性,可以使用flush方法进行冲刷
常用构造器:
BufferedOutputStream(OutputStream out) -------- 创建一个指定字节输出流的缓冲流对象
BufferedOutputStream(OutputStream out, int size)----创建一个指定字节输出流的缓冲流对象,并设置缓冲区的大小。
PS:当一次写的字节超出缓冲区大小,会出现溢出情况,溢出的字节会先写出去
常用方法:
void write(int b)-----写int数据的低八位,写入缓冲区内
void write(byte[] b,int off,int len)-----写一个指定长度的字节数组,写入缓冲区
BufferedInputStream:字节缓冲输入流
在读取字节时,也是一个字节一个字节的读,次数多,效率低。 使用缓冲输入流,内部维护了一个缓冲区,默认8192个字节,也就是8KB,先一次性将缓冲区装满等待读取, 当将缓冲区的数据读完,缓冲区再次存储后续数据。读取的次数明显降低,反之效率高。
构造器:
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int size)
常用方法:
int read(byte[] bs)----读取缓冲区里的字节存储bs中,
当一次性读取的字节小于缓冲区,我们是从缓冲区里读数据,效率高。
当一次性读取的字节超出缓冲区大小,不使用缓冲区,直接从文件里读。
int read(byte[] bs,int off,int len)
3、数据字节流
与缓冲流一样,父类都是过滤字节流( FilterOutputStream/FilterInputStream )
DataOutputStream/DataInputStream
这两个类提供了几个特殊的方法,可以直接写基本数据类型
数据输出流:DataOutputStream
构造器:
DataOutputStream(OutputStream out)------创建一个指定字节输出流的数据输出流对象
常用方法:
除了提供写一个字节和写一个字节数组的方法外,还提供了
writeByte(byte b)
writeShort(int s)
writeInt(int i )
writeLong(long l)
writeFloat(float f)
writeDouble(double d)
writeChar(int c)
writeBoolean(boolean b)
writeBytes(String s)
writeUTF(String s)
4、对象流
有的时候我们可能需要将内存中的对象持久化到硬盘上,或者将硬盘中的对象信息读到内存、中,这个时候我们需要使用对象输入输出流。
序列化:是对象转换成一个字节序列的过程,是一个写操作(ObjectInputStream)
反序列化:一个字节序列转换成对象的过程,是一个读操作(ObjectOutputStream)
ObjectOutputStream
构造器:
ObjectOutputStream(OutputStream out) --------- 创建一个指定字节输出流的对象输出流对象。
常用方法:除了提供一些基本数据类型的写方法外,还提供了
void writeObject(Object obj)-------将内存中的对象持久化到硬盘上
ObjectInputStream
构造器:
ObjectInputStream(InputStream out)-----------创建一个指定字节输入流的对象输入流对象。
常用方法:除了提供一些基本数据类型的写方法外,还提供了
void readObject(Object obj)----从硬盘上读取一个字节序列,转换成对象Serializable:序列化接口
如果想将对象序列化,那么对象的类型必须实现此接口。此接口内什么都没有,只是一个序列化标识。String中提供了serialVersionUID常量:
作用:每个能序列化的对象,在被序列化时,系统会默认给此对象的类提供序列化版本号。
不同的平台默认提供的序列化版本号多数情况下不会相同。因此,当我们反序列化
时,如果硬盘里存储的对象的版本号与当前设计的类型的版本号不一致,会出现运行
时异常:java.io.InvalidClassException
这种情况称为不兼容问题
如果我们想解决不兼容问题。我们应该手动提供版本号。尽可能的相同,这样来解决
不兼容问题。
另外一种情况:
序列化过后,可能会修改类型,如果使用默认提供的版本号,在反序列化
时,会出现异常;如果手动提供版本号,不出现异常,多出来的成员变量
以类型的默认值的形式,赋值给反序列化的对象。
transient:成员变量的一个修饰词,可以理解为瘦身。
有的时候在序列化对象时,我们不需要将对象的某些成员变量的值持久化到硬盘上,(因为不重要),此时,我们可以在这些成员变量前添加修饰词transient。(保存时进行减肥)
字符流 (只能够传输文本文件)
在输入输出操作时,以字符为单位进行操作,默认是unicode编码集
1、字符流的抽象父类分别是-------Writer\Reader
Writer提供了字符输出流的常用方法
void close()
void write(char[] cbuf)------写一个字符数组
void write(char[] cbuf, int off, int len)------写字符数组的一部分
void write(int c)---------写一个字符
void write(String str)--------写一串字符
write(String str, int off, int len) ---------写字符串的一部分Reader提供了字符输入流的常用方法
int read()-------读一个字符,存储到int的低16位
int read(char[] cbuf)----------将数据读进字符数组中,返回的是读取的有效字符个数
int read(char[] cbuf, int off, int len)------------将字符读入数组的一部分
2、子类中转换流:
OutputStreamWriter: 将字符转换成字节写出到硬盘上。
构造器:
OutputStreamWriter(OutputStream out)
创建一个指定字节输出流的字符输出流对象,采用的是系统默认的编码集
OutputStreamWriter(OutputStream out, Charset cs)
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
OutputStreamWriter(OutputStream out, String charsetName)
创建一个指定字节输出流的字符输出流对象,采用指定编码集write(int a)
当a的低16位,如果被设计成相应的字符时,如果两个字节都为有效字节,
会写出两个。如果低16位对应是无效字符,或者是有效字节只有一位时,
会写出一个字节。
InputStreamReader:将字节转换成字符读进程序中。
构造器:
InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader。
InputStreamReader(InputStream in, Charset cs)
InputStreamReader(InputStream in, CharsetDecoder dec)
InputStreamReader(InputStream in, String charsetName)
创建一个指定字符集的字节输入流的字符输入流对象。
3、缓冲流:
PrintWriter:提供了丰富的方法,比BufferedWriter更加常用,此类型提供了行自动刷新的功能。构造器:
PrintWriter(File file)
PrintWriter(OutputStream out)----------可以追加
PrintWriter(OutputStream out, boolean autoFlush) ----可以追加
PrintWriter(String fileName)
PrintWriter(Writer out)
可设置编码集,也可以再设置追加
PrintWriter(Writer out, boolean autoFlush)
可设置编码集,也可以再设置追加
上述构造器,有第二个参数的,可以设置为true,表示行自动刷新。且在使用写的时候使用
的是println才有行自动刷新的功能,这么设置在传入缓冲区时,会自动调用一个flush方法。
只有一个参数的构造器,相当于两个参数时,设置为false的情况,
即取消了行自动刷新的功能。
常用方法:
void println():通过写入行分隔符字符串来终止当前行。
void println(boolean x) :打印一个布尔值,然后终止该行。
void println(char x):打印一个字符,然后终止该行。
void println(char[] x):打印字符数组,然后终止行。
void println(double x) :打印双精度浮点数,然后终止行。
void println(float x):打印一个浮点数,然后终止该行。
void println(int x):打印一个整数,然后终止该行。
void println(long x):打印一个长整型,然后终止行。
void println(Object x):打印一个对象,然后终止该行。
void println(String x):打印一个字符串,然后终止行。
BufferedReader:提供了一个缓冲区
构造器:
BufferedReader(Reader in) -----创建使用默认大小的输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz) ------ 创建使用指定大小的输入缓冲区的缓冲字符输入流。
方法:
String readLine()
读一行字符串,读至换行符号为止,返回的数据不包含换行符。
当返回值为null时,表示读至文件末尾。
4、文件字符流:
FileWriter/FileReader
FileWriter:相当于OutputStreamWriter与FileOutputStream合起来的功能,内部也维护了一个缓冲区,但是需要手动flush
构造器:
FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)
append:表示追加,但是此流不能设置字符集。
常用方法与OutputStreamWriter的差不多
FileReader:相当于InputStreamReader和FileInputStream合起来的功能内部也维护了一个缓冲区。
构造器:
FileReader(File file)
FileReader(String fileName)
常用方法与InputStreamReader相似