文章目录
Java的IO流
一、Java的IO流介绍
在Java中IO流常常存储于java.io包中,通常IO流分为输入输出(Input/Output)。
1.1输入(Input)
输入就是可以让程序从外部系统获得数据(核心含义就是“读”,用来读取外部数据)常见的应用有:用播放器打开一个视频的内容;读取某些硬件系统的数据到程序中。
1.2输出(Output)
输出就是将程序输出数据给外部系统从而可以操作外部系统(核心含义就是“写”,将数据写出到外部系统)常见的应用有:将数据写到硬盘中;将数据写到数据库系统中,就是类似于我们要注册一个会员。
二、数据源
数据源(Data Source)就是类似于提供数据的原始媒介。常见的应用有:数据库、文件等等。
数据库还分为源设备和目标设备这两类。
源设备:是为程序提供数据,一般是对应输入流。
目标设备:程序数据的目的地,一般对应输出流。
他们之间的关系为:文件通过源设备将数据传给程序,而程序又可以通过目标设备将数据传回给文件。
三、流的概念
流就是一连串的连续动态数据的集合,在Java的IO流中我们可以将流看作一个管道,其包含输入输出流,Source通过输入流将数据信息传给程序,而程序又通过输出流将数据信息传给目的地。
就类似于我们从外部将东西传给程序就要使用输入流,我们从程序传给外部就要使用输出流。
四、Java中的四大IO抽象类
在Java中,其分有四大IO抽象类为InputStream/OutputStream和Reader/Writer这四个IO抽象类,这四个IO抽象类是所有IO流类的抽象父类。
我们也可以通过字节流和字符流来区分这四大IO抽象类,
字节流为InputStream和OutputStream,通常是以Stream结尾的流。
字符流为Reader和Writer,通常是以Reader/Writer结尾的流。
4.1InputStream
在JavaIO流中,InputStream是字节输入流的所有类的父类(不能实例化)。
常用方法有:
int read() //通过读取一个字节的数据,并将字节的值作为int类型返回(返回的数值在0-255之间的值),未读取则返回-1,则表示读取结束
在使用InputStream结束的时候,我们必须关闭他,避免占用内存,
void close() //关闭输入流对象,释放相关的系统资源
4.2OutputStream
OutputStream是所有字节输出流所有类的父类,是将字节发到某个目的地。
常用方法有:
void write(int n) //向目的地写入一个字节
void close() //关闭输出流对象,释放相关系统内存
4.3Reader
Reader(为字符输入流)是读取字符流,数据单位为字符。
常用方法有:
int read() //读取一个字符的数据,将字符值作为int类型返回(0-65535),如果未读出字符,则返回-1,表示读取结束
void close() //关闭流对象
4.4Writer
Writer是用于输出的字符流。
常用方法有:
void writer(int n) //向输出流中写入一个字符
void close() //关闭输出流对象
4.5InputStream/OutputStream和Reader/Writer的区别
InputStream/OutputStream和Reader/Writer这四大IO抽象类中,InputStream/OutputStream为字节输入输出流;
Reader/Writer为字符输入输出流。
五、输入流与输出流的区别
输入流:就是通过数据源将数据流传给程序,常用的有InputStream和Reader结尾的流;
输出流:就是通过程序将数据流传给目的地,常用的有OutputStream和Writer结尾的流。
按处理对象分类的话,就分为节点流和处理流,
节点流:直接去链接数据源的那个流对象。
处理流:不直接去链接数据源的那个流对象。
就好比数据源想要传给程序,就必须通过节点流来传送,而处理流则是在节点流的基础上将其包装。
六、IO流的体系(常用类)
在Java中,IO流的常用类有:
Object:File(对文件、目录进行包装)、RandomAccessFile(不是Java的IO流体系)、InputStream、OutputStream、Reader、Writer。
常用类很多时候都是成对出现的:
FileInputStream/FileOutputStream //节点流:对文件进行输入输出,以字节为单位直接操作“文件”
ByteArrayInputStream/ByteArrayOutputStream //节点流:以字节为单位直接操作“字节数组对象”
ObjectInputStream/ObjectOutputStream //处理流:以字节为单位直接操作“对象”
DataInputStream/DataOutputStream //处理流:以字节为单位直接操作“基本数据类型与字符串类型”
FileReader/FileWriter //节点流:以字符为单位直接操作“文本文件”
BufferedReader/BufferedWriter //处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写的效率
BufferedInputStream/BufferedOutputStream //处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高读写的效率
InputStreamReader/OutputStreamWriter //处理流:将字节流对象转化为字符流对象
PrintStream //处理流:将OutputStream进行包装,可以方便输出字符
值得注意的是Reader方法只能一次读取一个字符(所对应的Ascill数码值),因此我们可以通过循环来实现多次读取。
七、File类
File类为File对象针对的是文件或者目录转换对象的包装类,可以代表一个文件或目录,也可以实现获取文件和目录的属性功能。
7.1File类常用方法
1.针对文件操作
createNewFile() //创建新文件
delete() //直接从硬盘删除
exists() //查询文件是否存在
getAbsolutePath() //获取绝对路径
getPath() //获取相对路径
getName() //获取文件名,相当于调用toString
isFile() //判断是否为文件
length() //查看文件的字节数
isHidden() //测试文件是否被这个抽象路径名是一个隐藏文件
2.针对目录操作
exists() //查询目录是否存在
isDirectory() //判断当前路径是否为目录
mkdir() //创建目录
getParentFile() //获取当前目录的父级目录
list() //返回一个字符串数组,包含目录中的文件和目录的路径名
listFiles() //返回一个File数组,表示用此抽象路径名表示且目录中的文件
7.2File的基本使用
public class FileDemo{
public static void main(String[] args) throws Exception{
//创建一个File对象
File file = new File(pathname:"C:/a.txt"); //目录则为"C:/a"
System.out.println(file.createNewFile());
}
}
输出结果为:true
注意:在Java编译时候使用流对象常常会出现报错,因此我们常常将其抛出去或者catch住,通常我们都将其catch住,结构为:
try{
}catch(Exception e){
e.printStackTrace();
}
八、常用流对象
文件字节流:FileInputStream/FileOutputStream(适合读取所有类型的文件,包括图像、视频、文本文件等)
九、通过缓冲区提高读写效率
缓冲区可以提高IO流的读写效率,适合读取较大的图片。
byte[] buff = new byte[1024];
//创建一个缓冲区,提高读写效率,byte数组长度一般为2的整数幂
int temp = 0; //定义一个临时变量
while ((temp = fis.read(buff))!=-1){
fos.write(buff,off:0,temp);
}
方法二:通过创建一个字节数组,作为缓冲区,数组长度是通过输入流对象的available()返回当前文件的预估长度来定义的。(效率更快,但占用内存较大)
主要代码为:
byte[] buff = new byte[fis.available()];
fis.read(buff);
fos.write(buff);
fos.flush();
十、通过字节缓冲流提高读写效率
缓冲流是一种处理流(包装流),对文件或数据源频繁的读写操作时效率低,可使用缓冲流将数据缓存起来。
就比如BufferedInputStream和BufferedOutputStream这两个流逝缓冲字节流通过内部缓冲数组来提高效率。
主要代码为:
FileInputStream fis = null;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try{
fis = new FileInputStream(name:"d:a.jpg");
bis = new BufferedInputStream(fis);
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(bis ! = null){
bis.close(); //关闭流顺序:后开的先关闭
}
}
}
十一、定义文件拷贝工具类
主要代码为:
public static void copyFile(String src,Strinf des){
//定义字节缓冲流
copyFile(src:"路径",des:"地名");
}
十二、字符缓冲流
BufferedReader(缓冲输入流)/BufferedWriter(缓冲输出流),可以增加缓存机制,提高读写文件的效率。
12.1BufferedReader(缓冲输入流)
主要代码为:
FileReader fr = null;
BufferedReader br = null;
try{
fr = new FileReader(fileName:"d:/sxt.txt");
br = new BufferedReader(fr); //进行包装
String temp = " "; //定义的是Str类型,不是int类型
while((temp = br.readLine())! = null){
System.out.println(temp);
}
12.2BufferedWriter(缓冲输出流)
在字符输出缓冲流中,可以使用newLine()这个方法来实现换行处理,基本与缓冲输入流相似。
十三、通过字符缓冲流实现文本文件的拷贝
使用此方法效率会更高。主要代码为:
public static void copyFile(String src,String des){
//定义字符缓冲流,并且将其实例化
while((temp = br.readLine()) ! = null){
bw.writer(temp);
bw.newline(); //可以实现读一行写一行
}
十四、通过字符缓冲流文件中的内容添加行号
主要代码为:
String temp = " ";
int i = 1 ;
while ((temp = br.readLine()) ! = null){
bw.write(str:i + "," + temp); //可以将序号放在前面
bw.newLine();
i++;
}
bw.flush();
十五、对象流
对象流是存储数据的数据模型,分为序列化(写的过程)和反序列化(读的过程),类似于在A中将字节装入包中传给B,B再把字节序列转化为JAVA的对象。
主要作用有:
持久化:把对象字节序列永久的保存在硬盘中。
网络通信:在网络上传送对象的字节序列。
15.1对象流分类
ObjectOutputStream代表对象输出流,他的writeObject(Object obj)方法可对指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
ObjectInputStream代表对象输入流,他的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable接口的类的对象才能被序列化,Serializable接口是一个空接口,只起到标记作用。
十六、操作基本数据类型
数据流只能实现对基本数据类型和字符串类型的读写,并不能对java对象进行读写操作(字符串除外),但是在对象流中除了能实现对基本数据类型进行读写操作以外,还可以对java对象进行读写操作。
十七、操作对象
ObjectOutputStream可以将一个内存中java对象通过序列化的方式写入到磁盘的文件中,被序列化的对象必须实现Serializable这个序列化接口,否则会抛出异常。