一、IO流的含义
IO流主要是输入输出(input/output)系统功能。
输入(input)是指:可以让程序从外部系统获得数据(核心是读)。
读取硬盘上的文件内容到程序。例如:播放器打开一个视频文件,word打开一个文档。
读取网络上某个位置的内容到程序。例如:浏览器输入网址,打开网址对应的内容;下载网络上某个文件。
读取数据库的数据到程序。
读取某些系统硬盘数据到程序。例如:车载电脑读取雷达扫描信息到程序;温控系统等;
【简而言之:(数据)---->(程序)即,数据通过一个程序被体现出来】
输出(output)是指:程序输入数据给外部系统从而可以操作外部系统(核心是写)。
将数据写入到磁盘中。例如:我们编辑完一个文档,将文档进行保存。
将数据写到数据库的系统中。例如;我们注册一个会员,实际是后台程序向数据库写入一条记录。
将数据写到某些硬件系统中。例如:导弹系统导航程序将新的路径输出到飞控子系统,飞控子系统根据数据修正飞行路径。
【简而言之:(程序)---->(数据)即,由程序对数据进行的一个操作,记录保存等】
二、数据源
数据源 Date Source,提供数据的原始媒介。常见的数据源有:数据库、文件、内存等。
数据源分为:源设备、目标设备。
源设备:为程序提供数据,一般对应输入流。
目标设备:程序数据目的地,一般的对应输出流。
三、流的概念
流是一个抽象、动态的概念,是一串连续动态数据集合。
即,一个传输动作。
四、Java中四大IO流抽象类(重要)
所有流都是从Java四大IO流抽象类中派生出来的。
1.字节流
字节流,一次读取一个字节byte这种流使万能的,什么类型都可以读,包括,声音,图片,文件。
字节输入流InputStream
常用方法:
int read():读取一个字节数据,并将字节的值作为int 返回类型(0~255之间的一个值),如果未读出则返回-1。
void close():关闭输入流对象,释放资源。
字节输出流OutputStream
常用方法:
void write(int n):目的地写入一个字节。
void close():关闭输出流对象,释放资源。
2.字符流
字符流,一次读取一个字符,这个流只能读纯文本
读取字符流Reader
常用方法:
int read():读取一个字符数据,并将字节的值作为int 返回类型(0~65535之间的一个值),如果未读出则返回-1。
void close():关闭输入流对象,释放资源。
输出字符流Writer
常用方法:
void write(int n):向输入流中写入一个字符。
void close():关闭输入流对象,释放资源。
五、流的概念细分
1.按流的方向:
- 输入流:数据流从数据源到程序(以InputStream、Reader结尾的流)
- 输出流:数据流从程序到目的地(以OutputStream、Writer结尾的流)
2.按处理的数据单元:
- 字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,如FileInputStream。
- 字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader。
3.按处理对象不同:
- 节点流:可以直接从数据源或者目的地读写数据,如FileInputStream,FileReader等。
- 处理流:不直接连接到数据源或目的地,是处理流的流,对其他流处理提高程序的性能,如BufferedInputStream,BufferedReader,也叫包装流。
六、Java中IO流体系
1.InputStream/OutputStream
字节流的抽象类
2.Reader/Writer
字符流的抽象类
3. FilelnputStream / FileOutputStream
节点流:以字节为单位直接操作文件”
4. ByteArrayinputStream / ByteArrayOutputStream
节点流:以字节为单位直接操作字节数组对象
5.ObjectinputStream/ ObjectOutputStream
处理流:以字节为单位直接操作“对象
6. DatalnputStream / DataOutputStream
处理流:以字节为单位直接操作“基本数据类型与字符串类型”
7. FlleReader / FileWriter
节点流:以字符为单位直接操作文本文件”(注意;只能读写文本文件)
8. BufferedReader / BuferedWriter
处理流:将 Reader / Writer 对象进行包装,增加缓存功能,提高读写效率。
9. BufferedlnputStream / BufferedOutputStream
处理流:将 InputStream / OutputStream 对象进行包装,增加缓存功能,提高读写效率
10. InputStreamReader / OutputStreamWriter
处理流:将字节流对象转化成字符流对象
11. PrintStream
处理流:将 OutputStream 进行包装,可以方便地输出字符,更加灵活
七、File类
File类是Java提供的针对磁盘中的文件或目录转换对象的包装类,一个File对象可以代表一个文件或者目录,File对象可以实现获取文件和目录属性等功能,可以实现对文件目录的创建,删除等功能。
File类针对文件的一些操作方法:
1.createNewFile()
//创建新文件
2.delete()
//直接从磁盘上删除
3.exists()
//查询磁盘中文件是否存在
4.getAbsolutePath()
//获取绝对路径
5.getPath()
//获取相对路径
6.getName()
//获取文件名,相当于调用一个toString方法
7.isFile()
//判断是否是文件
8.length()
//查看文件中的字节数
9.isHidden()
//测试文件是否被这个抽象路径名是一个隐藏文件
针对操作目录的一些方法
1.exists()
//查询目录是否存在
2.isDirectory()
//判断当前路径是否为目录
3.mkdir()
//创建目录
4.getParentFile()
//获取当前目录的父级目录
5.list()
//返回一个字符串数组,包含目录中的文件和目录的路径名
6.listFiles
//返回一个file数组,表示用此抽象路径名表示目录中的文件
八、通过缓冲区提高读写效率
方法一:
通过创建一个指定长度的字节数组作为缓冲区,以此来提高IO流的读写效率。该方式适用于读取较大的图片时的缓冲区的定义。注意:缓冲区的长度一定为2的整数幂。一般情况下1024长度较为合适。
例如:
byte[] buff=new byte[1024];
//创建一个数组,作为缓存区
int temp =0;
while((temp=fis.read(buff))!=-1)
//read()返回的是数组的长度,返回1024
//一次返回一整个数组
{file.write(buff,0,temp);}
方法二:
通过创建一个指定长度的字节数组作为缓冲区,数组的长度是通过输入流对象的available()返回前文件的预估长度来定义。在读写文件时,是在一次读写操作中完成文件读写操作的。注意:如果文件过大,那么对内存的占用也是较大的。所以大文件不建议使用该方法。
FileInputStream fis =null;
FileOutputStream fos=null;
fis =new FileInputStream(...);
fos =new FileOutputStream(...);
byte [] buff=new byte[fis.available()];
fis.read(buff);
fos.flush();
九、通过字节缓冲流提高读写效率
Java 缓冲流本身并不具有 IO流的读取与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来一样,因此缓冲流是一种处理流(包装流)。
当对文件或者其他数据源进行频繁的读写操作时,效率比较低,这时如果使用缓冲流就能够更高效的读写信息。因为缓冲流是先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。
因此,缓冲流还是很重要的,我们在IO操作时记得加上缓冲流来提升性能。
BufferedInputStream 和 BufferedOutputStream 这两个流是缓冲字节流,通过内部缓存数组来提高操作流的效率。
十、字符缓冲流
BufferedReader/BufferedWriter 增加了缓存机制,大大提高了读写文本的效率。
readline();//在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取
newline();//字符输出缓冲流,换行处理
十一、转换流
InputStreamReader/OutputStreamWriter 用来实现将字节流转化成字符流。
比如:
System.in 是字节流对象,代表键盘的输入,如果我们想按行接收用户的输入时,就必须用到缓冲字符流 BufferedReader 特有的方法 readLine (),但是经过观察会发现在创建 BufferedReader 的构造方法的参数必须是一个 Reader 对象,这时候我们的转换流 InputStreamReader 就派上用场了。而 System.out 也是字节流对象,代表输出到显示器,按行读取用户的输入后,并且要将读取的一行字符串直接显示到控制台,就需要用到字符流的 write ( String str )方法,所以我们要使用 OutputStreamWriter 将字节流转化为字符流。
十二、字符输出流
在Java的IO流中专门提供了用于字符输出的流对象PrintWriter。该对象具有自动行刷新缓冲字符输出流,特点是可以按行写出字符串,并且可以通过println();方法实现自动换行。
十三、字节数组流
ByteArrayInputStream和ByteArrayOutputStream经常用在需要流和数组之间转化的情况。
1.字节数组输入流
FileInputStream是把文件当作数据源,ByteArrayInputStream是把内存中的字节数组对象当作数据源。
2.字节数组输出流
ByteOutputStream流对象是把流中的数据写入到字节数组中。
十四、数据流
数据输入流和数据输出流。
字符串类型作为数据源。从而允许程序以与机器无关的方式从底层输入输出流中操作 Java 基本数据类型与字符串类型。
DatalnputStream 和 DataOutputStream 提供了可以存取与机器无关的所有 Java 基础类型数据(如:int ,double,String等)的方法。
十五、对象流
1.Java对象的序列化和反序列化
当两个进程远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。比如,我们可以通过 http 协议发送字符串信息:我们也可以在网络上直接发送 Java 对象。发送方需要把这个 Java 对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再恢复为 Java 对象才能正常读取。
把 Java 对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为 Java 对象的过程称为对象的反序列化。
对象序列化的作用有如下两种:
- 持久化:把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。
- 网络通信:在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传递。
2.序列化涉及的类和接口
ObjectOutputStream n 代表对象输出流,它的 writeObject ( Object obj )方法可对参数指定的
obj 对象进行序列化,把得到的字节序列写到一个目标输出流中。ObjectinputStream 代表对象输入流,它的 readObject ()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了 Serializable 接口的类的对象才能被序列化。 Serializable 接口是一个空接口,只起到标记作用。
3.将对象序列化到文件
ObjectOutputStream 可以将一个内存中的 Java 对象通过序列化的方式写入到磁盘的文件中。被序列化的对象必须要实现 Serializable 序列化接口,否则会抛出异常。
十六、随机访问流
RandomAccessFile 可以实现两个作用:
- 实现对一个文件做读和写的操作。
- 可以访问文件的任童位置。 不像其他流只能按照先后顺序读取。
1. RandomAccessFile ( String name , String mode )
//name 用来确定文件;mode 取_ r 读或 rw 可读写),通过 mode 可以确定流对文件的访问权限。
2. seek ( long a )
//用来定位流对象读写文件的位置, a 确定读写位置钜离文件开头的字节个数。
3. getFilePointer ()
//获得流的当前读写位置。
十七、Apache IO包
JDK 中提供的文件操作相关的类, 但是功能都非常基础,进行复杂操作时需要做大量编程工作。实际开发中,往往需要你自己动手编写相关的代码,尤其在遍历目录文件时,经用到递归,非常繁琐。常Apache - commons 工具包中提供了 IOUtils / FileUtils ,可以让我们非常方便的对文件和目录进行操作。本文就是让大家对 IOUtils / FileUtils 类有一个全面的认识,便于大家以后开发与文件和目录相关的功能。
Apache IOUtis 和 FileUtils 类库为我们提供了更加简单、功能更加强大的文件操作和 IO流操作功能。非常值得大家学习和使用。
FileUitls常用方法:
cleanDirectory
//清空目录,但不删除目录。
contentEquals/
/比较两个文件的内容是否相同。
copyDirectory
//将一个目录内容拷贝到另一个目录,可以通过 FileFilter 过滤需要拷贝的文件。
copyFile
//将一个文件烤贝到一个新的地址。
copyFileToDirectory
//将一个文件烤贝到某个目录下。
copylnputStreamToFile
//将一个输入流中的内容拷贝到某个文件。
deleteDirectory
//删除目录。
listFiles
//列出指定目录下的所有文件。
openInputSteam
//打开指定文件的输入流。
readFileToSting
//将文件内容作为字符串返回
readLines
//将文件内容按行返回到一个字符串数组中。
size
//返回文件或目录的大小
write
//将字符串内容直接写到文件中。
writeByteArrayToFile
//将字节数组内容写到文件中。
writeLines
//将容器中的元素的toString方法返回的内容依次写入文件中。
IOUitls的常用方法:
buffer方法
//将传入的流进行包装,变成缓冲流。并可以通过参数指定缓冲大小。
closeQueitly方法
//关闭流
contentEquals方法
//比较两个流中的内容是否一致。
copy方法
//将输入流中的内容拷贝到输出流中,并可以指定字符编码。
copylarge方法
//将输入流中的内容拷贝到输出流中,适合大于2G内容的拷贝。
linelterator方法
//返回可以迭代毎一行内容的迭代器。
read方法
//将输入流中的部分内容读入到字节数组中。
readFuly方法
//将输入流中的所有内容读入到字节数组中。
readLine方法
//读入输入流内容中的一行。
toBuferedinputStream , toBuferedReader
//将输入转为带缓存的输入流。
toByteArray , toCharArray
//将输入流的内容转为字节数组、字符数组。
toString
//将输入流或数组中的内容转化为字符串。
write方法
//向流里面写入内容。
writeLine方法
//向流里面写如一行内容。