zoukankan      html  css  js  c++  java
  • java进阶(33)--IO流

    一、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代表文本的追加

      (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("
    hello 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("
    这是继续使用包装流追加的文字");
            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

  • 相关阅读:
    USACO 2008 Mar Silver 3.River Crossing 动态规划水题
    常见经验总结
    Ikki's Story IV
    洛谷P1993 小K的农场_差分约束_dfs跑SPFA
    洛谷P3275 [SCOI2011]糖果_差分约束_判负环
    Integer Intervals POJ
    洛谷 P2365 任务安排_代价提前计算 + 好题
    [NOI2005]瑰丽华尔兹 动态规划 + 单调队列
    Shoot the Bullet ZOJ
    background-clip 和 background-origin
  • 原文地址:https://www.cnblogs.com/mrwhite2020/p/14305950.html
Copyright © 2011-2022 走看看