流的基本概念以及文件专属的四个流(1)

流的基本概念

1、IO流,什么是IO?
    I:Input
    O:Output
    通过IO可以完成硬盘文件的读和写。

2、IO的分类?
    有多种分类方式:
        一种方式是按照流的方向进分类:
            (1)以内存作为参照物,
               往内存中存,叫做输入。或者叫做读。
               从内存中取,叫做输出。或者叫做写。

         另一种方式是按照读取数据方式不同进行分类:
            (2)按照读取数据的方式
                【1】有的流是按照字节的方式读取数据,一次读取一个byte,等同于一次读取8个二进制位,
                    这种流是万能的,什么类型的文件都可以读取。包括:文本文件,声音文件。视频文件等等。
                        a中国bc张三fe
                        第一次读:一个字节,正好读到'a'(char在java中占用两个字节)
                        第二次读:一个字节,正好读到'中'字符的一半
                        第三次读:一个字节,正好读到'中'字符的另一半

                【2】有的流是按照字符的方式读取的,一次读取一个字符,这种流是为了方便读取普通文本文件
                   而存在的,种种流不能读取:图片、声音、视频等文件。只能读取纯文本文件,连word文档都
                   无法读取。
                        假设文件file.txt,采用字符流的话是这样读的:
                            a中国bc张三fe
                            第一次读取:'a'字符('a'字符在windows系统中占用一个字节。)
                            第二次读:'中'字符('中'字符在windows系统中占用两个字节。)
3、java中所有的流都是在java.io.*;下。
   java中主要还是研究:
        怎么new流对象。
        调用流对象的那个方法是读,那个方法是写。

4、java IO流有四大家族。
    四大家族的首领:
        java.io.InputStream     字节输入流
        java.io.OutputStream    字节输出流

        java.io.Reader          字符输入流
        java.io.Writer          字符输出流

        四大家族的首领都是抽象的。(abstract class)

        所有流都实现了:
            java.io.Closeable接口,都是可关闭的,都有close()方法。
            流毕竟是一个管道,这是实现内存和硬盘之间的通道,用完之后一定要关闭,
            不然会耗费(占用)很多资源。养成好习惯:用完流一定要关闭。

        所有的---输出流---都实现了:
            java.io.Flushable接口,都是可刷新的,都有flush()方法
            养成一个好习惯,输出流在最终输出之后,一定要记得flush()
            刷新一下,这个刷新表示将通道/管道当中剩余未输出的数据
            强行输出完(清空管道!)刷新的作用就是清空管道。
            注意:如果没有flush()方法,可能会导致丢失数据。

        注意:
            在java中只要“类名”以Stream结尾的都是字节流。
            以“Reader/Writer”结尾的都是字符流。

4、java.io包下需要掌握的流有16个:

    文件专属:
        java.io.FileInputStream
        java.io.FileOutputStream
        java.io.FileReader
        java.io.FileWriter
    转换流:(将字节流转换成字符流)
        java.io.InputStreamReader
        java.io.OutputStreamWriter
    缓冲流专属:
        java.io.BufferedReader
        java.io.BufferedWriter
        java.io.BufferedInputStream
        java.io.BufferedOutputStream
    数据流专属:
        java.io.DataInputStream
        java.io.DateOutputStream
    标准输出流:
        java.io.PrintWriter
        java.io.PrintStream
    对象专属流:
        java.io.ObjectInputStream
        java.io.ObjectOutputStream

 */

文件专属流

文件专属:
        java.io.FileInputStream(掌握)
        java.io.FileOutputStream(掌握)
        java.io.FileReader
        java.io.FileWriter

 


1、java.io.FileInputStream

package com.tjdz.javaSE.IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
java.io.FileInputStream:
    1、文件字节输入流,万能的,任何的类型文件都可以采用这个流来读。
    2、字节的方式,完成输入的操作,完成读的操作(硬盘--->内存)


 */
public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            // 创建文件字节输入流对象
            // 文件路径:E:\Text document\file\temp.txt(IDEA工具会自动把\变成\\,因为java中\表示转义)

            //FileInputStream fis = new FileInputStream("E:\\Text document\\file\\temp.txt");
            //写成/也是可以的
            fis = new FileInputStream("E:/Text document/file/temp.txt");

            //开始读
            int realData = fis.read(); // 这个方法的返回值读取到的“字节”本身
            System.out.println(realData); //97
            realData = fis.read();
            System.out.println(realData); //98
            realData = fis.read();
            System.out.println(realData); //99
            realData = fis.read();
            System.out.println(realData); //100
            realData = fis.read();
            System.out.println(realData); //101
            realData = fis.read();
            System.out.println(realData); //102

            //已经读到文件的末尾了,在读的时候读取不到任何数据,返回-1
            realData = fis.read();
            System.out.println(realData); //-1

            realData = fis.read();
            System.out.println(realData); //-1


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            //在finally语句块当中确保流一定要关闭
            if(fis != null){ //  避免空指针异常
                //关闭流的前提是:流不是null,流是null的时候没必要关闭
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}



package com.tjdz.javaSE.IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
对第一个程序进行该进。循环方式。

分析这个程序的缺点:
    一次读取一个byte,这样内存和硬盘之间交互太频繁,基本上大部分时间/资源
    都耗费在交互上面了。能不能一次读取多个字节呢。
 */
public class FileInputStreamTest02 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("E:/Text document/file/temp.txt");
            /*
            while(true){
                int readDate = fis.read();
                if(readDate == -1){
                    break;
                }
                System.out.println(readDate);
            }
            */

            //改造while循环
            int readDate = 0;
            while((readDate = fis.read()) != -1){
                System.out.println(readDate);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}




package com.tjdz.javaSE.IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
int read(byte[] b)
    一次最多读取 b.length  个字节
    减少硬盘和内存交互,提高程序执行效率
    往byte[]数组当中读。
 */
public class FileInputStreamTest03 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            // IDEA默认的当前路径在哪?(工程Protect的根就是IDEA的默认当前路径。)
            fis = new FileInputStream("temp.txt");

            //开始读,采用byte数组,一次读取多个字节。最多读取“数组.length”个字节
            byte [] bytes = new byte[4]; //准备一个4个长度的byte数组,一次性读取4个字节
            // 这个方法的返回值是:读取到的字节数量(不是字节本身)
            int readCount = fis.read(bytes);
            System.out.println(readCount); //第一次读到了四个字节
            //将字节数组全部转换成字符串
            //System.out.println(new String(bytes)); //abcd
            //不应该全部转换,应该读取多少个转多少个
            //System.out.println(new String(bytes,0,readCount));

            readCount = fis.read(bytes);  //第二次只能读取到两个字节
            System.out.println(readCount); //2
            //System.out.println(new String(bytes,0,readCount));

            readCount = fis.read(bytes);  //1个字节都没读取到返回-1
            System.out.println(readCount);  // -1

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}




package com.tjdz.javaSE.IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
最终版
 */
public class FileInputStreamTest04 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("temp.txt");
            byte[] bytes = new byte[4];
            /*
            while(true){
                int readCount = fis.read(bytes);
                if(readCount == -1){
                    break;
                }
                System.out.print(new String(bytes,0,readCount));
            }
            */
            //改造while循坏
            int readCount = 0;
            while((readCount = fis.read(bytes)) != -1){
                System.out.print(new String(bytes,0,readCount));
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}





package com.tjdz.javaSE.IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/*
FileInputStream类的其他方法;
    int available()     :返回流当中剩余的没有读到的字节数量
    long skip(long n)   :跳过集合字节字节不读
 */
public class FileInputStreamTest05 {
    public static void main(String[] args) {
        FileInputStream fis =null;
        try {
            fis = new FileInputStream("temp.txt");
            System.out.println("总字节数:"+fis.available());
            //读1个字节
            int readByte = fis.read();  //转换为对应额ASCII码值
            System.out.println(readByte);   // 这里对应输出的是ASCII码值
            // 还剩下可以读的字节数量:5
            System.out.println("还剩下可以读的字节数量:"+fis.available());

           //byte [] bytes = new byte[fis.available()];//不适合大文件,因为byte数组不是太大
           //不需要循环
            // 只需要读一次就行
           //int readCount = fis.read(bytes);
           //System.out.println(new String(bytes));

            //skip跳过几个字节不读取
            fis.skip(3);
            System.out.println("跳过后流的数量:"+fis.available());

            byte[] bytes = new byte[fis.available()];
            int readCount = fis.read(bytes);
            System.out.println(readCount);
            System.out.println(new String(bytes));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2、java.io.FileOutputStream

package com.tjdz.javaSE.IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/*
文件字节输出流
    从内存到硬盘。
    void write(byte[] b)
        写 b.length字节从指定的字节数组的输出流。

 */
public class FileOutStreamTest01 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            //myfile文件不存在时,会自动新建
            //这种方式谨慎使用,这种方式先回将源文件清空,然后再重新写入。
            //fos = new FileOutputStream("myfilm");

            //若想追加
            //以追加的方式在文件末尾写入,不会清空源文件内容。
            fos = new FileOutputStream("myfilm",true);
            //开始写
            byte[] bytes = {97,98,99,100};
            //将byte数组全部写出
            fos.write(bytes);  //abcd
            //将bytes的一部分写入
            fos.write(bytes,0,2); //ab

            //字符串
            String s = "我是一个中国人";
            //将字符串转换成bytes数组。
            byte[] bytes1 = s.getBytes();
            //写
            fos.write(bytes1);

            //写完之后,最终一定要刷新
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3、java.io.FileReader

package com.tjdz.javaSE.IO;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/*
FileReader:
    文件字符输入流,只能读取普通文本
    读取文本内容时,比较方便,快捷。
 */
public class FileReaderTest {
    public static void main(String[] args) {
        FileReader reader = null;
        try {
            //创建文件字符流输入流
            reader = new FileReader("temp.txt");

            //准备一个char数组
            char[] chars = new char[10];
            reader.read(chars);
            for(char c : chars){
                System.out.print(c);
            }

            /*//开始读
            char [] chars = new char[4];  // 一次读取4个字符
            int readCount =0;
            while((readCount = reader.read(chars)) != -1){
                System.out.print(new String(chars,0,readCount));
            }*/
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4、java.io.FileWriter

package com.tjdz.javaSE.IO;

import java.io.FileWriter;
import java.io.IOException;

/*
FileWriter:
    文件字符输出流。写。
    只能输出普通文本。
 */
public class FileWriterTest {
    public static void main(String[] args) {
        FileWriter out = null;
        try {
            //创建字符输出流对象
            //out = new FileWriter("file");

            //如果想在后面一直不删除原来的情况下追加
            out = new FileWriter("file",true);

            //开始写
            char [] chars = {'我','是','中','国','人'};
            out.write(chars);
            out.write(chars,2,3);

            out.write("\n");
            out.write("我是一名java软件工程师!");

            //刷新
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

上一篇:springboot 打jar 包部署时 读取外部配置文件


下一篇:ffmpeg解码流程