Java高级学习篇之IO流
Posted ITWEL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java高级学习篇之IO流相关的知识,希望对你有一定的参考价值。
(一)什么是IO?
IO是InputOutput的缩写,表示的是输入输出流。
(1) I :Input,表示的是将数据从硬盘的文件中输入到内存,称为Read操作。(2) O :Output,表示的是将数据从内存输出到硬盘的文件,也称为write操作
Java程序中,对于数据的操作是以"流“的方式进行的。
说明:
① 通过IO流来完成硬盘上数据的读与写(作用)
② java.io包下提供了各种”流“类和接口,用以获取不同种类的数据,并通过标准的方 法输入或输出数据
(二)流的分类
(1)根据操作数的基本单位:字节流(8位)、字符流(16位)
(2)根据数据的流向: 输入流、输出流
(3)根据流的对象: 节点流、处理流
①如何区分输入和输出流的流向呢??
站在以内存为核心的角度上:
若是读取数据,就是 从 磁盘文件---->内存
若是写入数据,就是 从 内存 ------>磁盘文件
②字节流 VS 字节流??
字节流在操作时本身不会用到缓冲区(内存),是文件本身直接进行操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。
体系结构如下:
表格如下:
抽象基类 | 节点流 | 缓冲流 |
InputStream | FileInputStream | BufferedInputStream |
OutputStream | FileOutputStream | BufferedOutputStream |
Writer | FileWriter | BufferedWriter |
Reader | FileReader | BufferedReader |
说明:
(1)FileInputStream和FileOutputStream是用来处理字节的
(2)FileWriter和FileReader是用来处理字符的
使用场景
字符流:文本文件 <.txt .java .c .cpp等>
字节流:非文本文件 <.jpg .mp3 .mp4 .avi .doc .ppt等>
(三)使用介绍
I. <FileWriter>&<FileReader>
(1)基本介绍
FileWriter指的是从内存向文件写入字符数据。
FileReader指的是从文件向内存读出字符数据。
(2)使用步骤
①实例化File类的对象(指明要读出或写入的文件路径)
②创建一个具体的流对象(操作具体数据)
③通过循环进行数据的读入或读出
④流的关闭(必要操作)
(3)实例代码
FileReader测试
@Test
public void testFileReader()
FileReader tr= null;
try
//实例化File类的对象,指明路径
File file = new File("hello1.txt");
//创建具体的流对象,用来进行操作数据
tr = new FileReader(file);
//读写数据
int data;
while((data=tr.read())!=-1)
System.out.print((char)data);
catch (IOException e)
e.printStackTrace();
finally
//关闭对应的流
try
if(tr!=null)
//条件判断是为了防止出现空指针异常
tr.close();
catch (IOException e)
e.printStackTrace();
说明:
①通过read读入的是对应字符的ASCILL码值
②异常处理使用的是结构: try---catch---finally(流的关闭)
如果使用throws方法,可能造成内存泄漏
③流的关闭
数据库连接、输入输出流、Socket连接无法·通过垃圾回收机制进行回收,所以需要手手动关闭。
FileWriter测试
@Test
public void testFileWriter() throws IOException
//创建文件类对象
File file=new File("hello1.txt");
//创建流对象
FileWriter tr = new FileWriter(file,true);
//写入数据
tr.write("Welcome to China".toCharArray());
tr.write(" Jerry");
//关闭流
tr.close();
说明:
①再通过写入流向文件中写入数据时,可以直接使用write方法
说明:
②输出操作,对应的File可以不存在的。并不会报异常
③ File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
File对应的硬盘中的文件如果存在:
若流使用的构造器是:FileWriter(file,false) / FileWriter(file):对原有文件的 覆盖
若流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有 文 件基础上追加内容
常用的write()重载方法
(1)write(String str):将整个字符串写入
内部调用的是如下函数:
(2)write(char[]str,int offset,int end):将字符数组写入到文件中
FileWriter&FileReader测试
@Test
public void testFileRaW()
FileReader du= null;
FileWriter wr= null;
try
//创建File类的对象,指明读入和读出的文件
File file=new File("hello.txt");
File file1=new File("hello1.txt");
//创建输入流和输出流的对象
du = new FileReader(file);
wr = new FileWriter(file1,true);
//读数据并且写入数据
char [] tu=new char[5];
int number;
while((number=du.read(tu))!=-1)
String sr = new String(tu, 0, number);
wr.write(sr);
catch (IOException e)
e.printStackTrace();
finally
try
//关闭输入输出流
if(du!=null)
du.close();
if(wr!=null)
wr.close();
catch (IOException e)
e.printStackTrace();
II.<FileOutputStream>&<FileInputStream>
(1)基本介绍
FileInputStream指的是<磁盘文件-->内存>读取数据
FileOutPutStream指的是<内存-->磁盘文件>写出数据
(2)使用步骤
① 创建File文件类对象
② 创建字节流(FileOutputStream/FileInputStream)
③ 文件内容的读取和写入
④ 关闭输入&输出字节流
异常处理: try...catch...finally(关闭流)
(3)实例代码
FileOutputStream测试
@Test
public void testFileOutputStream()
FileOutputStream fos= null;
try
File fs=new File("hell5.txt");
fos = new FileOutputStream(fs);
fos.write(97);
//说明:97对应的字符是 a,将字符a写入到hell5.txt文件中
catch (IOException e)
e.printStackTrace();
finally
try
if(fos!=null)
fos.close();
catch (IOException e)
e.printStackTrace();
write的重载方法:
FileInputStream测试
@Test
public void testInputStream()
FileInputStream in= null;
try
File file=new File("hello.txt");
in = new FileInputStream(file);
byte[]bu=new byte[5];
int len;
while ((len=in.read(bu))!=-1)
String tr=new String(bu);
System.out.print(tr);
catch (IOException e)
e.printStackTrace();
finally
try
in.close();
catch (IOException e)
e.printStackTrace();
//输出结果:hello world tu?腑鍥?
说明:
输出结果中出现了乱码原因如下:
字节流是用来处理非文本文件,而.txt是非文本文件,所以在读取时并不是直接将一个字符读入,可能是将一个字符分两次读入,从而产生了乱码问题。
FileInputStream&FileOutputStream测试
@Test
public void copyFileIaO()
FileInputStream input= null;
FileOutputStream out = null;
try
//创建File类对象
File file1=new File("海豚.png");
File file2=new File("海豚1.png");
//创建输入流和输出流
input = new FileInputStream(file1);
out = new FileOutputStream(file2);
//数据的读入和读出
byte []buf=new byte[5];
int len;
while((len=input.read(buf))!=-1)
out.write(buf,0,len);
catch (IOException e)
e.printStackTrace();
finally
//输入输出流的关闭
if(input!=null)
try
input.close();
catch (IOException e)
e.printStackTrace();
if(out!=null)
try
out.close();
catch (IOException e)
e.printStackTrace();
应用:文件复制
public void copyFile(String initPath,String desPath)
FileInputStream input= null;
FileOutputStream out = null;
try
//创建File类对象
File file1=new File(initPath);
File file2=new File(desPath);
//创建输入流和输出流
input = new FileInputStream(file1);
out = new FileOutputStream(file2);
//数据的读入和读出
byte []buf=new byte[10];
int len;
while((len=input.read(buf))!=-1)
out.write(buf,0,len);
catch (IOException e)
e.printStackTrace();
finally
//输入输出流的关闭
if(input!=null)
try
input.close();
catch (IOException e)
e.printStackTrace();
if(out!=null)
try
out.close();
catch (IOException e)
e.printStackTrace();
@Test
public void testCopyFile()
long start=System.currentTimeMillis();
String srcPath="海豚.png";
String desPath="海豚1.png";
copyFile(srcPath,desPath);
long end = System.currentTimeMillis();
System.out.println("复制所花费的时间是:"+(end-start));
//运行结果为:复制所花费的时间是:265
III.Buffer flow(缓冲流)
(1)是什么?
缓冲流有名增强流,主要对节点流的读写读写速度进行增强。
(2)作用是?
提高流的读取和写入速率。
(3)分类
BufferedInputStream
BufferedOutputStream
BufferedWriter
BufferedReader
为何有如此功能?
主要是因为其在内部提供了一个缓存区(8kb),当读取数据时,先将数据读取到该缓冲区,当达到一定数量时,全部输出,依次进行,直到文件内容全部输出。
(3)如何用?
使用缓冲流将字节流对象包装一下就可以进行使用,读写速度更快。
public void copyFileWithBuffered(String srcPath,String desPath)
BufferedInputStream bis= null;
BufferedOutputStream bos= null;
try
//(1)造文件
File srcfile=new File(srcPath);
File desfile=new File(desPath);
//(2)造流
// 2.1 造节点流
FileInputStream fis=new FileInputStream(srcfile);
FileOutputStream fos =new FileOutputStream(desfile);
// 2.2 造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//(3)复制的细节:读取、写入
byte[]buffer =new byte[10];
int len;
while((len=bis.read(buffer))!=-1)
bos.write(buffer,0,len);
catch (IOException e)
e.printStackTrace();
finally
try
//(4)资源关闭(先关闭外层的流,再关闭内层的流)
if(bis!=null)
bis.close();
if(bos!=null)
bos.close();
//说明:关闭外层流的同时,内层流也会自动关闭(无需再手动关闭内层流)
catch (IOException e)
e.printStackTrace();
@Test
public void testCopyBuffered()
long start =System.currentTimeMillis();
String srcPath="海豚.png";
String desPath="海豚3.png";
copyFileWithBuffered(srcPath,desPath);
long end = System.currentTimeMillis();
System.out.println("执行复制所需要的时间是:"+(end-start));
//运行结果是:执行复制所需要的时间是:8
对比可得:使用缓冲流对文件进行读写后,其速度提高了数倍。
IV.The conversion stream(转换流)
(1)作用
实现 字节流<---->字符流 的相互转化
补充:
①解码:字节、字节数组 ----> 字符数组、字符串*
②编码:字符数组、字符串 ----> 字节、字节数组
(2)字符集
① ASCILL:美国标准的信息交换码用一个字节的7位可以表示。
② ISO8859-1:拉丁码表。欧洲码表用一个字节的8位表示。
③ GB2312:中国的中文编码表。最多两个字节编码所有字符。
④ GBK:中国的中文编码表的升级,融合更多的中文文字字符,最多两个字节编码。
⑤ Unicode:国际标准码,融合了目前人类使用的所有字符。
为每个字符分配了唯一的字符码,所有的文字都使用两个字节来表示。
⑥ UTF-8:变长的编码方式,可以使用1-4个字节来表示一个字符。
(3)实现代码
InputStreamReader&OutputStreamWriter测试
ASCII:美国标准信息交换码。* 用一个字节的7位可以表示。* ISO8859-1:拉丁码表。欧洲码表* 用一个字节的8位表示。* GB2312:中国的中文编码表。最多两个字节编码所有字符* GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码* Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。* UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。
@Test
public void test()
InputStreamReader isr= null;
OutputStreamWriter osw= null;
try
//创建文件类
File file1=new File("hello1.txt");
File file2=new File("hello2.txt");
//创建输入和输出流
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos= new FileOutputStream(file2);
isr = new InputStreamReader(fis);
osw = new OutputStreamWriter(fos,"GBK");
//读写过程
char[] tr=new char[20];
int len=0;
while((len=isr.read(tr))!=-1)
osw.write(tr,0,len);
catch (IOException e)
e.printStackTrace();
finally
try
isr.close();
osw.close();
catch (IOException e)
e.printStackTrace();
//运行结果:Welcome to China Jerry�й�(由于编码格式的不同所产生)
IV.RandomAccessFile
(1)介绍
直接继承于java.lang.Object类,实现了DataInput和DataOutput接口
既可以作为输入流也可以作为输出流。
(2)优点
可以使用该流对指定位置进行添加数据的操作。
(3)实例代码
@Test
public void test()
RandomAccessFile raf= null;
RandomAccessFile raf1= null;
try
raf = new RandomAccessFile(new File("hello1.txt"),"r");
raf1 = new RandomAccessFile(new File("hello9.txt"),"rw");
byte[]buf=new byte[1024];
int以上是关于Java高级学习篇之IO流的主要内容,如果未能解决你的问题,请参考以下文章