java进阶(33)--IO流

图解 | 原来这就是TCP

一、IO流概念:
1、基本概念
2、IO流分类
3、java.io流的四大家族
4、流的close和flush方法
5、java.id下常用的16个流

二、FileInputStream字节输入流
1、FileInputStream完成字节流输入的流程
2、使用while优化FileInputStream读取流程
3、FileInputStream最终版,使用byte数组读取
4、FileInputStream的available
5、FileInputStream的skip方法

三、FileOutputStream字节输出流
1、FileOutputStream概念
2、FileOutputStream输出流程
3、改进FileInputStream+String输出
4、文件复制(FileInputStream+FileOutputStream)

四、FileReader与FileWrite
1、FileReader概念
2、举例FileReader
3、FileWrite概念:
4、举例FileWrite:
5、复制普通文件(FileReader与FileWrite):

五、带有缓冲区的字符流
1、BufferedReader概念:
2、举例说明BufferedReader:
3、节点流与包装流
4、BufferedWrite:带有缓冲区的字符输出流

六、数据流
1、DataOutputStream概念
2、举例说明:DataOutputStream
3、DataInputStream流概念:
4、举例说明:DataInputStream

七、标准输出流
1、PrintStream标准字节输出流:
2、更改标准输出流的输出方向
3、日志工具生成原理:

八、File类
https://www.cnblogs.com/mrwhite2020/p/14322392.html

九、对象流
https://www.cnblogs.com/mrwhite2020/p/14322446.html

十、IO和Properties
https://www.cnblogs.com/mrwhite2020/p/14322463.html

 ------------------------------------------分割线,以下为正文-------------------------------------------------

一、IO流概念:

1、基本概念

I:Input

O:Output

通过IO可以完成硬盘文件的读和写。

2、IO流分类

(1)按照流的方向分类:

输入流(Input)或者称为读(Reader)

输出流(Output)或者称为写(Write)

(2)按照读取数据方式不同分类:

字节流:按照字节方式读取数据,一次读取1个字节byte,等同一个8个二进制位,这种流是万能的,什么类型的文件都可以读取,包括:文本文件、图片、视频、声音等

字符流:按照字符方式读取数据,一次读取一个字符,这种流是为了方便读取普通文件而存在,这种流不能读取图片、声音、视频、word等,只能读取纯文本文件。

假设文件test.txt 内容为:"h世界"

字节流读取:第一次读'h'(占用一个字节),第二次读'世'字符的一半(占用一个字节)

字符流读取:第一次读'h'(占用一个字节),第二次读'世'字符(占用一个字符)

3、java.io流的四大家族

(1)java.io.InputStream字节输入流

(2)java.io.OutputStream字节输出流

(3)java.io.Reader字符输入流

(4)java.io.Writer字符输出流

在java中以Stream结尾都是字节流,以Reader/Writer结尾都是字符流

 4、流的close和flush方法

(1)close()

所有的流都实现java.io.closeble接口,都是可以关闭的,都右close方法。

流是一个管理,是内存与硬盘之间的通道,用完之后一定要关闭,不然会耗费很多资源,养成好习惯,用完流一定要关闭。

(2)flush()

所有的输出流都实现了java.io.Flushable接口,都可以刷新,都包含flush方法。

养成好习惯,输出流输出玩都需要flush刷新一下,表示将通道/管道当中的剩余未输出的数据强行输出完,即清空管道,没有使用flush方法会导致数据丢失

5、java.io下常用的16个流

(1)文件专属:

java.io.FileInputStream;
java.io.FileOutputStream;
java.io.FileReader;
java.io.FileWriter;

(2)转换流:字节流转为字符流

java.io.InputStream;
java.io.OutputStream;

(3)缓冲区专属:

java.io.BufferedInputStream;
java.io.BufferedOutputStream;
java.io.BufferedReader;
java.io.BufferedWriter;

(4)数据专属:

java.io.DataInputStream;
java.io.DataOutputStream;

(5)标准输出流:

java.io.PrintStream;
java.io.PrintWriter;

(6)对象专属:

java.io.ObjectInputStream;
java.io.ObjectOutputStream;

 

二、FileInputStream字节输入流

1、FileInputStream完成字节流输入的流程

(1)准备文件如下:

(2)创建字节流输入对象,Idea自动将路径变斜杠

 (3)alt+回车添加try+catch或者上报异常,这里选择try+catch

 (4)第二种文件路径编写方式"\"与"//"等价

 (5)增加finally语句且初始化流放在try+catch语句外,并添加流的关闭,流关闭前需要增加流的判空ifn可默认生成 if(fis==null)

 (6)增加流的读取,并添加try+catch使用alt+回车,这里建议选择第一种异常

第一种:增加catch使用细粒度的异常

第二种:方法声明异常

第三种:替换外层FIleNotFount为IO异常

第四种:内层在增加try+catch

 (7)查看打印结果为a对应的字符ascII码值97

 (8)可重复读取6次,最后一次读取不到返回-1

 2、使用while优化FileInputStream读取流程

 3、FileInputStream最终版,使用byte数组读取

 4、FileInputStream的available

(1)查看剩余的字节数

 (2)available的作用:可以不适用while循环,直接一次读取全部的字节,但是不适合大的文件,因为byte数组不能太大

5、FileInputStream的skip方法

 

三、FileOutputStream字节输出流

1、FileOutputStream概念:

字节输出流,从内存到硬盘

2、FileOutputStream输出流程

(1)使用byte数组+write方法+flush方法写入

 (2)检查文件结果,相对路径为项目根目录下:

(3)再次执行,会将原文件中内容覆盖,依然输出:abcdab 

(4)修改构造方法,true代表文本的追加

Ice系列--基于IceGrid的部署方案

  (5)查看相对路径下的文本执行结果:文本追加了内容

 3、改进FileInputStream+String输出

(1)使用String转byte数组输出

 

 (2)查看输出结果,追加一段String字符串

4、文件复制(FileInputStream+FileOutputStream)

(1)流程:拷贝过程是一边读、一边写;文件类型任意,是万能的

(2)举例文件复制:

 1 package JAVAADVANCE;  2 
 3 import java.io.FileInputStream;  4 import java.io.FileNotFoundException;  5 import java.io.FileOutputStream;  6 import java.io.IOException;  7 
 8 public class TestAdvance33IOTest08 {  9     public static void main(String[] args) { 10         FileInputStream fis=null; 11         FileOutputStream fos=null; 12         try { 13             //创建一个输入对象流
14             fis=new FileInputStream("D:\\javaTest\\inFile\\甜蜜家园第01集.mp4"); 15             //创建一个输出对象流
16             fos=new FileOutputStream("D:\\javaTest\\outFile\\甜蜜家园第01集.mp4"); 17             //准备一个byte数组,1024byte=1KB,*1024=1M,一次最多读1M
18             byte[] bytes=new byte[1024*1024]; 19             int readCount=0; 20             while ((readCount=fis.read(bytes))!=-1) 21  { 22                 //读取多少,写多少
23                 fos.write(bytes,0,readCount); 24  } 25  fos.flush(); 26         } catch (FileNotFoundException e) { 27  e.printStackTrace(); 28         } catch (IOException e) { 29  e.printStackTrace(); 30         } finally { 31             //fos与fis的关闭分开try catch比较好,避免互相影响,有流没有关闭
32             if (fos != null) { 33                 try { 34  fos.close(); 35                 } catch (IOException e) { 36  e.printStackTrace(); 37  } 38  } 39             if(fis!=null){ 40                 try { 41  fis.close(); 42                 } catch (IOException e) { 43  e.printStackTrace(); 44  } 45  } 46  } 47 
48 
49 
50 
51  } 52 }

查看文件输出结果

 \

 

四、FileReader与FileWrite

1、FileReader概念

文件字符输入流,只能读取普通文本,读取文本内容时比较方便、快捷

2、举例FileReader

 1 package JAVAADVANCE;  2 import java.io.*;  3 public class TestAdvance33IOTest09FileReader {  4     public static void main(String[] args) {  5         FileReader reader= null;  6         try {  7             //创建字符输入流
 8             reader=new FileReader("C:\\Users\\Mr.White\\IdeaProjects\\javaAdvance\\myTestFile01");  9             //开始读,使用char数组,一次读取4个字符
10             char[] chars=new char[4]; 11             int readCount=0; 12             while ((readCount=reader.read(chars))!=-1){ 13                 System.out.println(new String(chars,0,readCount)); 14  } 15         } catch (FileNotFoundException e) { 16  e.printStackTrace(); 17         } catch (IOException e) { 18  e.printStackTrace(); 19         } finally { 20             if (reader != null) { 21                 try { 22  reader.close(); 23                 } catch (IOException e) { 24  e.printStackTrace(); 25  } 26  } 27  } 28  } 29 }

检查源文件与读取的内容

 3、FileWrite概念:

文件字符输出流,只能输出普通文本

4、举例FileWrite:

 1 package JAVAADVANCE;  2 import java.io.FileWriter;  3 import java.io.IOException;  4 public class TestAdvance33IOTest10FileWrite {  5     public static void main(String[] args) {  6         FileWriter out = null;  7         try {  8             //创建字符输出流对象,true使用追加写入模式,否则重新执行会覆盖
 9             out=new FileWriter("fileWriteTest01",true); 10             //开始写,使用char数组
11             char[] chars={'我','是','中','国','人'}; 12             //写入全部char数组
13  out.write(chars); 14             //再写入部分char数组,第3个字符开始,3个字符
15             out.write(chars,2,3); 16             //直接写入String
17             out.write("我是个JAVA工程师"); 18  out.flush(); 19         } catch (IOException e) { 20  e.printStackTrace(); 21         }finally { 22             if (out != null) { 23                 try { 24  out.close(); 25                 } catch (IOException e) { 26  e.printStackTrace(); 27  } 28  } 29  } 30  } 31 }

查看输出结果,相对路径为工程根目录下

 5、复制普通文件(FileReader与FileWrite):

(1)使用FileReader与FileWrite进行拷贝,只能拷贝普通文本文件

(2)举例复制普通文件:

 1 package JAVAADVANCE;  2 import java.io.FileNotFoundException;  3 import java.io.FileReader;  4 import java.io.FileWriter;  5 import java.io.IOException;  6 public class TestAdvance33IOTest11NormalFileCopy {  7     public static void main(String[] args) {  8         FileReader in =null;  9         FileWriter out = null; 10         try { 11             //创建字符输入流
12             in=new FileReader("D:\\javaTest\\inFile\\fileWriteTest01"); 13             //创建字符输出流
14             out=new FileWriter("D:\\javaTest\\outFile\\fileWriteTest01"); 15             //一边读一边写
16             char[] chars=new char[1024*512]; //一次读取1M文件
17             int readCount=0; 18             while ((readCount=in.read(chars))!=-1){ 19                 out.write(new String(chars,0,readCount)); 20  } 21             //写完后刷新
22  out.flush(); 23         } catch (FileNotFoundException e) { 24  e.printStackTrace(); 25         } catch (IOException e) { 26  e.printStackTrace(); 27         } finally { 28             if (in != null) { 29                 try { 30  in.close(); 31                 } catch (IOException e) { 32  e.printStackTrace(); 33  } 34  } 35             if (out != null) { 36                 try { 37  out.close(); 38                 } catch (IOException e) { 39  e.printStackTrace(); 40  } 41  } 42  } 43  } 44 }

查看复制后结果

 

五、带有缓冲区的字符流

1、BufferedReader概念:

带有缓冲区的字符输入流,使用此流不需要自定义char数组,或者说不需要自定义byte数组,自带缓冲区。

2、举例说明BufferedReader:

(1)准备文件

 (2)按照行读取文件

package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest12BufferedReader { //异常先抛出
    public static void main(String[] args) throws IOException { FileReader reader=new FileReader("D:\\javaTest\\inFile\\fileWriteTest02"); //FileReader为节点流,BufferedReader为包装流/处理流
        BufferedReader br=new BufferedReader(reader); //读第一行
        String firstLine = br.readLine(); System.out.println(firstLine); //读第二行
        String secondLine = br.readLine(); System.out.println(secondLine); //读第三行
        String thirdLine = br.readLine(); System.out.println(thirdLine); //只需要关闭最外层的流,对于包装流来说
 br.close(); } }

(3)循环读取全部文件

 1 package JAVAADVANCE;  2 import java.io.BufferedReader;  3 import java.io.FileReader;  4 import java.io.IOException;  5 public class TestAdvance33IOTest12BufferedReader02 {  6     //异常先抛出
 7     public static void main(String[] args) throws IOException {  8         FileReader reader=new FileReader("D:\\javaTest\\inFile\\fileWriteTest02");  9         //FileReader为节点流,BufferedReader为包装流/处理流
10         BufferedReader br=new BufferedReader(reader); 11         //使用String字符串读取
12         String s=null; 13         while ((s=br.readLine())!=null){ 14  System.out.println(s); 15  } 16         //只需要关闭最外层的流,对于包装流来说
17  br.close(); 18  } 19 }

检查执行结果

(4)print方法测试readLine方法不带换行符

 1 package JAVAADVANCE;  2 import java.io.BufferedReader;  3 import java.io.FileReader;  4 import java.io.IOException;  5 public class TestAdvance33IOTest12BufferedReader02 {  6     //异常先抛出
 7     public static void main(String[] args) throws IOException {  8         FileReader reader=new FileReader("D:\\javaTest\\inFile\\fileWriteTest02");  9         //FileReader为节点流,BufferedReader为包装流/处理流
10         BufferedReader br=new BufferedReader(reader); 11         //使用String字符串读取
12         String s=null; 13         while ((s=br.readLine())!=null){ 14             //print方法测试readLine方法不带换行符
15  System.out.print(s); 16  } 17         //只需要关闭最外层的流,对于包装流来说
18  br.close(); 19  } 20 }

查看执行结果

3、节点流与包装流

(1)节点流与包装流都是相对而言

(2)举例说明:节点流与包装流

以下例子:

in与reader:in为节点流,reader为包装流

reader与br:reader与节点流,br为包装流

package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest12BufferedReader03 { //异常先抛出
    public static void main(String[] args) throws IOException { FileInputStream in=new FileInputStream("D:\\javaTest\\inFile\\fileWriteTest02"); //通过InputStreamReader转换流将字节流转换为字符流
        InputStreamReader reader=new InputStreamReader(in); BufferedReader br =new BufferedReader(reader); //使用String字符串读取
        String line=null; while ((line=br.readLine())!=null){ //print方法测试readLine方法不带换行符
 System.out.println(line); } //只需要关闭最外层的流,对于包装流来说
 br.close(); } }

查看运行结果:

 4、BufferedWrite:带有缓冲区的字符输出流

(1)举例说明BufferedWrite

package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest13BufferedWrite { //异常先抛出
    public static void main(String[] args) throws IOException { BufferedWriter out=new BufferedWriter(new FileWriter("D:\\javaTest\\outFile\\fileWriteTest02")); out.write("hello world"); out.write("\nhello kitty"); out.flush(); out.close(); } }

查看执行结果

 (2)使用包装流追加输出

package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest13BufferedWrite02 { //异常先抛出
    public static void main(String[] args) throws IOException { BufferedWriter out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\javaTest\\outFile\\fileWriteTest02",true))); out.write("\n这是继续使用包装流追加的文字"); out.flush(); out.close(); } }

查看执行结果:

 

六、数据流

1、DataOutputStream概念:

数据专属的流

这个流可以将数据连同数据的类型一并写入文件

 注意:这个文件不同普通文本文档(这个文件使用记事本打不开)

2、举例说明:DataOutputStream

package JAVAADVANCE; import java.io.*; public class TestAdvance33IOTest14DataOutputStream01 { //异常先抛出
    public static void main(String[] args) throws IOException { //创建数据专属字节输出流
        DataOutputStream dos=new DataOutputStream(new FileOutputStream("D:\\javaTest\\outFile\\fileWriteTest03")); byte b=100; short s=200; int i=300; float t=400F; double d=3.14; boolean sex=false; char c='a'; dos.writeByte(b); dos.writeShort(s); dos.writeInt(i); dos.writeFloat(t); dos.writeDouble(d); dos.writeBoolean(sex); dos.writeChar(c); dos.flush(); dos.close(); } }

查看文件结果:无法使用记事本或notepad++打开,需要使用DataInputStream流打开,并且读的顺序需要与写的顺序一致。

 3、DataInputStream流概念:

数据字节输入流,DataOutputStream流写的文件只能使用DataInputStream打开,并且读的顺序需要和写的顺序一致。

4、举例说明:DataInputStream

 1 package JAVAADVANCE;  2 import java.io.*;  3 public class TestAdvance33IOTest15DataInputStream01 {  4     //异常先抛出
 5     public static void main(String[] args) throws IOException {  6         //创建数据专属字节输入流
 7         DataInputStream dis =new DataInputStream(new FileInputStream("D:\\javaTest\\outFile\\fileWriteTest03"));  8         //开始读,读的顺序要与写的时候保持一致。
 9         byte b= dis.readByte(); 10         short s=dis.readShort(); 11         int i=dis.readInt(); 12         float t =dis.readFloat(); 13         double d=dis.readDouble(); 14         boolean sex=dis.readBoolean(); 15         char c=dis.readChar(); 16  dis.close(); 17  System.out.println(b); 18  System.out.println(s); 19  System.out.println(i); 20  System.out.println(t); 21  System.out.println(d); 22  System.out.println(sex); 23  System.out.println(c); 24 
25  } 26 }

查看显示结果

 

 七、标准输出流

1、PrintStream标准字节输出流:

标准字节输出流,默认输出到控制台。

 1 package JAVAADVANCE;  2 import java.io.IOException;  3 import java.io.PrintStream;  4 public class TestAdvance33IOTest16PrintStream01 {  5     //异常先抛出
 6     public static void main(String[] args) throws IOException {  7         //标准输出流直接输出到控制台
 8         System.out.println("hello world");  9         //换一种写法
10         PrintStream ps=System.out; 11         ps.println("hello zhangsan"); 12         ps.println("hello lisi"); 13         //标准输出流不需要手动关闭
14  } 15 }

2、更改标准输出流的输出方向

 1 package JAVAADVANCE;  2 import java.io.FileOutputStream;  3 import java.io.IOException;  4 import java.io.PrintStream;  5 public class TestAdvance33IOTest16PrintStream01 {  6     //异常先抛出
 7     public static void main(String[] args) throws IOException {  8         //更改标准输出流的输出方向,指向log文件
 9         System.setOut(new PrintStream(new FileOutputStream("log"))); 10         //再次输出
11         System.out.println("hello world"); 12         System.out.println("hello kitty"); 13  } 14 }

查看项目根目录的输出文件

  3、日志工具生成原理:

package JAVAADVANCE; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.Date; public class TestAdvance33IOTest16LogTest { //异常先抛出
    public static void log(String msg) { try { PrintStream out=new PrintStream(new FileOutputStream("log.txt",true)); //改变文件的输出方向
 System.setOut(out); //当前日期格式
            Date nowTime = new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); String strTime=sdf.format(nowTime); } catch (FileNotFoundException e) { e.printStackTrace(); } } }

编写测试程序开始测试日志打印

1 package JAVAADVANCE; 2 public class TestAdvance33IOTest16LogTest { 3     public static void main(String[] args) { 4         //测试工具是否好用
5         TestAdvance33IOTest16PrintStream02.log("调用了Sytem的gc()方法,建议启动垃圾回收"); 6         TestAdvance33IOTest16PrintStream02.log("调用了userService的dosome()方法"); 7         TestAdvance33IOTest16PrintStream02.log("用户正在尝试登录,验证失败"); 8  } 9 }

查看输出结果

 

八、File类

File类参照如下章节:

https://www.cnblogs.com/mrwhite2020/p/14322392.html

 

九、对象流

对象流、序列化与反序列化参考如下章节:

https://www.cnblogs.com/mrwhite2020/p/14322446.html

 

十、IO和Properties

IO和Properties联合使用参考如下章节:

https://www.cnblogs.com/mrwhite2020/p/14322463.html

 

【原创】Linux虚拟化KVM-Qemu分析(八)之virtio初探

相关推荐

发表评论

路人甲

网友评论(0)