io

IO流:(Input,Output)

我们在做项目时,除了自定义的一些数据外,还可能需要从"外界"引入数据,或者将数据导出到"外界"。这时,我们需要I/O操作。

外界:指的可能是  键盘,显示器,硬盘,另外一个程序。

输入:又叫读入操作         数据从"外界"流向程序
输出:又叫写出操作         数据从程序流向"外界"

: 就是数据序列, 一经创建成功,就会打开一个通道。所以使用完应该进行关闭操作。

流的概念和作用

流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO流的分类

(1)按照流向分类
           输入流
           输出流

对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。  

(2)按照处理的数据单位分类
          字节流(8位的字节)
          字符流(16位的字节)

字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:

  • 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
  • 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

(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)
       skip(int n)

OutputStream:定义了字节输出流的常用方法

       void close()
       void flush():冲刷,作用是将流的数据,冲刷进文件中
       void write(int b):写一个字节
       void write(byte[] b):写一个字节数组
       void write(byte[] b,int off,int len)

文件字节流:FileInputStream/FileOutputStream

文件字节输入流:FiIeInputStream

(1)构造器:

FileInputStream(File file) 
创建一个指定路径的File对象的文件输入流对象
FileInputStream(String name) 
创建一个指定路径的字符串的文件输入流对象

(2)常用方法

int read()
                 读取该流中的一个字节数据,即8位二进制,存储到一个int数
                 据的低八位上              
                 如果返回-1,读至文件末尾,

long skip(long n)
               跳过流中n个字节

int read(byte[] b)
                读取字节存入byte数组中,最多能读b.length个字节
                返回的是实际读取的字节个数

int available()
                查看此输入流中剩余的字节数量

文件字节输出流:FileOutputStream

(1)构造器:

FileOutputStream(File file) 
FileOutputStream(File file, boolean append) 
FileOutputStream(String name)
FileOutputStream(String name, boolean append)
创建一个指定路径的输出流对象,append表示在文件末尾追加
 PS:如果指定路径下的文件名不存在,会自动创建。
       如果父路径不存在,则报异常FileNotFoundException

(2)常用方法:

void write(int b)
写出参数b中的一个字节,int类型的低八位。

void write(byte[] b)
将字节数组b中的字节按顺序写出

void write(byte[] b,int off,int len)
将字节数组b中的字节按顺序写出,从下标off,写len个

字节缓冲流:BufferedInputStream/BufferedOutputStream

字节缓冲输入流:BufferedInputStream

在读取字节时,也是一个字节一个字节的读,次数多,效率低。
使用缓冲输入流,内部维护了一个缓冲区,默认8k,先一次性将缓冲区装满等待读取.
当将缓冲区的数据读完,缓冲区再次存储后续数据。读取的次数明显降低效率高      

(1)构造器:

BufferedInputStream(InputStream is);
BufferedInputStream(InputStream is,int size);

(2)常用方法:

int read(byte[] bs)

读取缓冲区里的字节存储bs中,
当一次性得去的字节小于缓冲区,我们是从缓冲区里读数据。
此时,效率高  

当一次性读取的字节超出缓冲区大小。
不使用缓冲区,直接从文件里读。

int read(byte[] bs,int off,int len)

字节缓冲输出流:BufferedOutputStream

在写数据时,如果一个字节一个字节的写,写的次数明显很多,效率就会变得很低。
如何提高效率呢。
缓冲输出流的特点是:在流里维护了一个缓冲区,写字节时,先将字节
写入缓冲区, 当缓冲区满时,再一次性的将数据写到文件里。这样就
降低了写的次数,因此提高了效率。
因此缓冲输出流缺失即时性,可以使用flush方法进行冲刷
    
(1)常用构造器:

BufferedOutputStream(OutputStream out)
创建一个指定字节输出流的缓冲流对象
BufferedOutputStream(OutputStream out,int size)
创建一个指定字节输出流的缓冲流对象,并设置缓冲区的大小
PS:当一次写的字节超出缓冲区大小,会出现溢出情况,溢出的字节会先写出到文件中    

(2)常用方法:

void write(int b):写int数据的低八位,写入缓冲区内
void write(byte[] b,int off,int len):写指定长度len的字节数组,写入缓冲区

数据字节流,与缓冲流一样,父类都是过滤字节流(FilterOutputStream/FilterInputStream)
这两个类提供了几个特殊的方法,可以直接写基本数据类型

字节数据流:DataInputStream/DataOutputStream

字节数据输入流:DataInputStream

字节数据输出流:DataOutputStream

(1)构造器:

DataOutputStream(OutputStream os):创建一个指定字节输出流的数据输出流对象
   
(2)常用方法:

除了提供写一个字节和写一个字节数组的方法外,还提供了如下方法      

writeByte(int b)
writeShort(int s) 
writeInt(int i)
writeLong(long l)
writeFloat(float f)
writeDouble(double d)
writeChar(int c)
writeBoolean(boolean b)
writeUTF(String s)

字节对象流:ObjectIntputStream /ObjectOutputStream

有的时候,我们可能需要将内存中的对象持久化到硬盘上,或者将
硬盘中的对象信息读到内存中,这个时候我们需要使用对象输入输出流。
    
序列化:是对象转换成一个字节序列的过程,是一个写操作
反序列化: 一个字节序列转换成对象的过程 ,是一个读操作

字节对象输入流:ObjectIntputStream 

(1)构造器:

ObjectIntputStream(OutputStream out) 
创建一个指定字节输入流的对象输入流对象。
          
(2)常用方法:

除了提供了一些基本数据类型的读方法外,还提供了

Object readObject():从硬盘上读取一个字节序列,转换成对象

字节对象输出流:ObjectOutputStream

(1)构造器:

ObjectOutputStream(OutputStream out) 
创建一个指定字节输出流的对象输出流对象。 
          
(2)常用方法:

除了提供了一些基本数据类型的写方法外,还提供了

void writeObject(Object obj):将内存中的对象持久化到硬盘上 

Serializable:序列化接口

如果想将对象序列化,那么对象的类型必须实现此接口。此接口内什么都没有,只是一个序列化标识。

serialVersionUID:

每个能序列化的对象,在被序列化时,系统会默认给此对象的类计算一个
序列化版本号。不同的平台默认提供的序列化版本号多数情况下不会相同。
因此当我们反序列时,如果硬盘里存储的对象的版本号与当前设计的类型
的版本号不一致。会出现运行时异常:
java.io.InvalidClassException,这种情况叫不兼容问题。
如果我们想解决不兼容问题。我们应该手动提供版本号。尽可能的相同
这样来解决不兼容问题

另外一种情况:
序列化过后,可能会修改类型,如果使用系统默认提供的
版本号,在反序列时,会有异常,如果手动提供,不出现异常
多出来的成员变量,以默认值的形式,赋值给反序列化回来的对象。

transient:成员变量的一个修饰词,可以理解为瘦身。

有的时候,在序列化对象时,我们不需要将对象的某些成员变量
值持久化到硬盘上(因为不重要),此时,我们可以在这些成员变量
添加修饰词transient(保存时,进行减肥)

字符流:

抽象父类:Writer/Reader

在输出输入操作时,以字符为单位进行操作,默认是unicode编码集字符流的抽象父类分别是Writer/Reader

Reader提供了字符输入流的常用方法

int read():读一个字符,存储到int的低16位
int read(char[] cbuf):将数据读进字符数组中,返回的是读取的有效字符个数
int read(char[] cbuf, int off, int len) :将字符读入数组的一部分   

Writer提供了字符输出流的常用方法

void close():关闭 
void write(char[] cbuf):写一个字符数组
void write(char[] cbuf, int off, int len):写一个字符数组的一部分 
write(int c):写一个字符
write(String str):写一串字符
write(String str, int off, int len) :写字符串的一部分 

字符转换流:InputStreamReader/OutputStreamReader

字符转换输入流:InputStreamReader

将字节转换成字符读进程序中

(1)构造器:

InputStreamReader(InputStream in) 
创建一个使用默认字符集的InputStreamReader。  
InputStreamReader(InputStream in, Charset cs) 
InputStreamReader(InputStream in, CharsetDecoder dec) 
InputStreamReader(InputStream in, String charsetName) 
创建一个使用指定字符集的InputStreamReader。

字符转换输出流:OutputStreamWriter

将字符转换成字节写出到硬盘上

(1)构造器:          

OutputStreamWriter(OutputStream out)
创建一个指定字节输出流的字符输出流对象,采用的是系统默认的编码集 
OutputStreamWriter(OutputStream out, Charset cs) 
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 
OutputStreamWriter(OutputStream out, String charsetName)
创建一个指定字节输出流的字符输出流对象,采用指定编码集。 

(2)常用方法:

write(int a);
当a的低16位,如果被设计成相应的字符时,如果两个字节都是
有效字节,会写出两个。如果低16位对应是无效字符,或是有效
字节只有一位时,会写一个字节。      

字符缓冲流:BufferedReader/PrintWriter

字符缓冲输入流:BufferedReader:

提供了一个缓冲区

(1)构造器:   

BufferedReader(Reader in) :创建使用默认大小的输入缓冲区的缓冲字符输入流。  
BufferedReader(Reader in, int sz): 创建使用指定大小的输入缓冲区的缓冲字符输入流。

(2)常用方法:  

String readLine():
读一行字符串,读至换行符号为止,返回的数据不包含换行符
当返回值为null时,表示读至文件末尾

字符缓冲输出流:PrintWriter

提供了丰富的方法,比BufferedWriter更加常用,此类型提供了行自动刷新的功能

(1)构造器:       

PrintWriter(File file) 
PrintWriter(OutputStream out)
PrintWriter(OutputStream out, boolean autoFlush)        
PrintWriter(String fileName) 
PrintWriter(Writer out) 
PrintWriter(Writer out, boolean autoFlush) 

上述构造器,有第二个参数的,可以设置为true,表示行自动刷新。  
只有一个参数的构造器,相当有两个参数时,设置为false的情况,即取消了行自动刷新的功能

(2)常用方法:
println() 通过写入行分隔符字符串来终止当前行。 
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)  

文件字符流:FileWriter/FileReader

文件字符输入流:FileReader

相当于InputStreamReader和FileInputStream合起来的功能内部也维护了一个缓冲区

(1)构造器:

FileReader(File file) 
FileReader(String fileName) 
常用方法与InputStreamReader的方法差不多

文件字符输出流:FileWriter:

相当于OutputStreamWriter与FileOutputStream合起来的功能,内部也维护了一个缓冲区,但是需要手动flush

(1)构造器:

FileWriter(File file)
FileWriter(File file, boolean append) 
FileWriter(String fileName) 
FileWriter(String fileName, boolean append)
append:表示追加,但是此流不能设置字符集。
常用方法与 OutputStreamWriter的差不多

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值