【狂神Java笔记】——Java I/0流(附代码)(更新中……)

一、I/O流

a. 基础知识

1. I/O流是什么

I:Input
O:Output

在这里插入图片描述

2. IO流的分类

输入流、输出流、字节流、字符流

输入流

以内存作为参照物,往内存中去,叫输入,或者叫——读

输出流

从内存中出来,叫输出,或者叫——写

字节流
  • 按照字节的方式读取数据,一次读取一个字节byte,等同于一次读取8个二进制位。
  • 这种流是万能的,什么类型的文件都可以读取,包括:文本文件,图片,声音文件,视频文件等…
字符流
  • 按照字符的方式读取数据,一次读取一个字符,叫字符流。
  • 这种流是为了方便读取普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件,只能读取存文本文件,连word文件都无法读取。

3. java中的I/O

Java中所有的流都在:java.io.*

4. I/O流的四大家族

  • java.io.InputStream字节输入流
  • ​java.io.OutputStream字节输出流
  • ​java.io.Reader字符输入流
  • java.io.Writer字符输出流

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

5. close()和flush()方法

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

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

注意:如果没有flush()可能会导致丢失数据。

6. 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.DataOutputStream

标准输出流:
java.io.PrintWriter
java.io.PrintStream(掌握)

对象专属流:
java.io.ObjectInputStream(掌握)
java.io.ObjectOutputStream(掌握)

b. 文件流

1. 代码——输入字节流 FileInputStream

(1)创建文件字节流文件,读取单字节

FileInputStream fis = null;
fis = new FileInputStream("E:\\JAVA\\JAVAma\\lianxi1\\IOStream\\test.txt");
int readDate = fis.read();//这个方法的返回值是:读取到的宇本身。
System.out.println(readDate);//97

package com.blue.FileInput;

//创建文件字节流文件
/*以下都是采用了绝对路径的方式
    文件路径:C:\Users\77\Downloads\Documents\07-JavaSE进阶每日复习与笔记 会制动把 \编程 \\,因为 java中的 \代表转义
    也可以写成C:/Users/77/Downloads/Documents/07-JavaSE进阶每日复习与笔记
*/
/*
java.io.FileInputStream
    1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读
    2.字节的方式,完成输入操作,完成读的操作(硬盘---->内存)
 */

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

public class FileInputStreamDemo1 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("E:\\JAVA\\JAVAma\\lianxi1\\IOStream\\test.txt");
            // 开始读
            int readDate = fis.read();//这个方法的返回值是:读取到的宇本身。
            System.out.println(readDate);//97

            readDate = fis.read();
            System.out.println(readDate);//98
            readDate = fis.read();
            System.out.println(readDate);//99
            readDate = fis.read();
            System.out.println(readDate);//100
            readDate = fis.read();
            System.out.println(readDate);//101
            readDate = fis.read();
            System.out.println(readDate);//102

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

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

(2)读取单字节–改进——循环方式

int readDate = 0;
while ((readDate = fis.read())!= -1)

package com.blue.FileInput;

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

// 对第一个程序进行改进。循环方式。 FileInputStreamDemo1
public class FileInputStreamDemo2 {
    public static void main(String[] args) {
        FileInputStream fis = null;

        try {
            fis = new FileInputStream("E:\\JAVA\\JAVAma\\lianxi1\\IOStream\\test.txt");
            /*
            while (true){

                int readData = fis.read();
                if (readData == -1){
                    break;
                }
                System.out.println(readData);
            }*/

            // 改造 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();
                }
            }
        }
    }
}

(3)读取多个字节

byte[] bytes = new byte[4];
int readCount = fis.read(bytes)

package com.blue.FileInput;

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

//继续改造,一次读取多个字节
/*
    int read(byte[] b)
        一次最多读取b.length个字节
        减少硬盘和内存的交互,提高程序的执行效率
        往byte[]数组当中读
 */
public class FileInputStreamDemo3 {

    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            //使用相对路径
            //IDEA当前的默认路径为,工程 Project的根就是IDEA的默认当前路径
//            fis = new FileInputStream("test.txt");
            fis = new FileInputStream("src/test1.txt");
            //开始读,采用byte数组,一次读取多个字节,最多读取“数组.length”个字节
            byte[] bytes = new byte[4];//一次最多读取四个字节
            // 这个方法的返回值是:取到的宁节数量。(不是字节本身)

            int readCount = fis.read(bytes);//第一次读到 4个宇
            System.out.println(readCount);//4
            //宇节数组全部转换成字符串
            System.out.println(new String(bytes));
            //不应该全部都转换,应该是读取了多少个宇节,转换多少个。
            System.out.println(new String(bytes,0,readCount));

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

            readCount = fis.read(bytes); //1个字节都没有读取到返回-1
            System.out.println(readCount);//-1
            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();
                }
            }
        }
    }
}

(4)读取多个字节–改进
package com.blue.FileInput;

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

//
public class FileInputStreamDemo4 {

    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("src/com/test2.txt");
            //准备一个byte数组
            byte[] bytes = new byte[4];
            /*while (true){
                int readCout = fis.read(bytes);
                if (readCout == -1){
                    break;
                }
                // 把 byte数组转换成字符串,读到多少个转换多少个
                System.out.print(new String(bytes,0,readCout));
            }*/
            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();
                }
            }
        }
    }

}

(5)读取多个字节–改进–跳过几个字节不读取
package com.blue.FileInput;

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

/*
其他常用的两个方法:
    int available() 返回流当中剩余的没有读到的字节数量
    long skip(long n) 跳过几个字节不读
 */
public class FileInputStreamDemo5 {

    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("test.txt");
            //读一个字节
//            int readByte = fis.read();

            /*
            System.out.println("剩下多少个字节没有读:" + fis.available());
            byte[] bytes = new byte[fis.available()];//这种方式不太适合太大的文件,因为bytes[]数组不能太大
            //这个方法有什么用
            //不需要循环了,直接读一次就可以
            int readCount = fis.read(bytes);
            System.out.println(new String(bytes));
            */

            //跳过几个字节不读取,这个方法以后可能也会用到
            fis.skip(3);
            System.out.println(fis.read());

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

2. 代码——输出字节流 FileInputStream

package com.blue.FileInput;

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

/*
    文件字节输出流,负责写
    从内存到硬盘
 */
public class FileOutputStreamDemo1 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            //myfile文件不存在的时候会自动新建!
            //这种方式谨慎使用,这种方式会先将原文件清空,然后重新写又。
//            fos = new FileOutputStream("myfile");

            // 以追加的方式在文件未尾写入。不会清空原文件内容。
            fos = new FileOutputStream("myfile",true);

            //开始写
            byte[] bytes = {97,98,99,100};
            //将byte数组全部写出!
            fos.write(bytes);//abcd
            //将byte数组的一部分写出!
            fos.write(bytes,0,2);//再写ab

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

            //写完之后,最后一定要刷新
            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. 代码—— 完成文件的拷贝

FileInputStream fis = null;
FileOutputStream fos = null;
byte[] bytes = new byte[1024 * 1024];//1B(一次最多考贝1MB。)
while ((readCount = fis.read(bytes)) != -1){
fos.write(bytes,0,readCount);

package com.blue.Copy;

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

/*
    使用 FiLeInputStream + FileOutputStream 完成文件的拷贝。
    持贝的过程应该是一边读,一边写。
    使用以上的字节流拷贝文件的时候,文件类型随意,万能的。什么样的文件都能考贝拷贝。
*/
public class CopyDemo01 {

    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //创建一个输入流对象
            fis = new FileInputStream("test.txt");
            //创建一个输出流对象
            fos = new FileOutputStream("src/com/blue/Copy/copy.txt");

            //最核心的:一边读,一边写
            byte[] bytes = new byte[1024 * 1024];//1B(一次最多考贝1MB。)
            int readCount = 0;
            while ((readCount = fis.read(bytes)) != -1){
                fos.write(bytes,0,readCount);
            }

            //刷新,输出流最后要刷新
            fos.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //分开 try,不要一起 try
            //一起 try的时候,其中一个出现异常,可能会影啊到另一个流的关闭。
            if (fis == null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos == null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

4. 代码——字符输入流FileReader

(1)while循环读

char[] chars = new char[4];//一次读取4个字符
while ((readCount = reader.read(chars)) != -1){

package com.blue.FileReader;

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

/*
FileReader:
    文件字符输入流,只能读取普通文本。
    读取文本内容时,比较方便,快捷。
 */
public class FileReadDemo01 {

    public static void main(String[] args) {
        FileReader reader = null;
        try {
            //创建文件字符输入流
            reader = new FileReader("src/com/blue/FileReader/yeah.txt");
            //开始读
            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();
                }
            }
        }
    }
}

输出为========================
blue
空山新雨后
天气晚来秋
Process finished with exit code 0
(2)for循环读

char[] chars = new char[4];//一次读取4个字符
reader.read(chars); //按照字符的方式取:第一次e,第二次,第三次风
for (char c : chars){
System.out.println(c);

package com.blue.FileReader;

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

/*
FileReader:
    文件字符输入流,只能读取普通文本。
    读取文本内容时,比较方便,快捷。
 */
public class FileReadDemo02 {

    public static void main(String[] args) {
        FileReader reader = null;
        try {
            //创建文件字符输入流
            reader = new FileReader("src/com/blue/FileReader/yeah.txt");
            //准备一个 char数组
            char[] chars  = new char[4];//一次读取4个字符
            //往 char数组中读
            reader.read(chars); //按照字符的方式取:第一次e,第二次,第三次风
            for (char c : chars){
                System.out.println(c);
            }

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

    }

}

输出为=============================
b
l
u
e

Process finished with exit code 0

5. 代码——字符输出流FileWriter

package com.blue.FileWriter;

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

/*
Filewriter
    文件字符输出流。写。
    只能输出普通文本
 */
public class FileWriterDemo01 {

    public static void main(String[] args) {
        FileWriter out = null;
        try {
            //创建文件宇符输出流对象
//            out = new FileWriter("src/com/blue/FileWriter/file.txt");
            out = new FileWriter("src/com/blue/FileWriter/file.txt",true);
            //开始写
            char[] chars = {'我','是','中','国','人'};
            out.write(chars);
            out.write(chars,2,3);

            out.write("我是一名学生");
            out.write("\n");

            //刷新
            out.flush();

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

}

文件内容
在这里插入图片描述

c. 缓冲流

1. 代码——带有缓冲区的字符输入流BufferedReader

package com.blue.BufferedReader;

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

/*
BufferedReader:
    带有缓冲区的字符输入流。
    使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲。
 */
public class BufferedReaderDemo01 {
    public static void main(String[] args) {

        FileReader reader = null;
        BufferedReader br = null;
        try {
            reader = new FileReader("CopyDemo02.java");

            // 当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:节点流。
            // 外部负责包装的这个流,叫做:包装流,还有一个名字叫做:处理流。
            // 像当前这个程序来说:FiLeReader就是一个节点流。BufferedReader就是包装流/处理流。
            br = new BufferedReader(reader);

            /*// 读一行
            String firstLine = br.readLine();
            System.out.println(firstLine);

            String secondLine = br.readLine();
            System.out.println(secondLine);

            String Line3 = br.readLine();
            System.out.println(Line3);*/

            // br.readLine()方法读取一个文本行,但不带换行符。
            String s = null;
            while ((s = br.readLine()) != null){
                System.out.println(s);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                //关闭流
                //对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭。(可以看源代码。
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

package com.blue.BufferedReader;

import java.io.*;

public class BufferedReaderDemo02 {
    public static void main(String[] args) {
        FileInputStream in = null;
        BufferedReader br = null;
        InputStreamReader reader = null;
        try {

            /*in = new FileInputStream("CopyDemo02.java"); //字节流

            // 通过转换流转换(InputStreamReader将字节流转换成字符流。
            // in是节点流。reader是包装流。
            reader = new InputStreamReader(in); // 通过转换流转换

            // 这个构造方法只能传一个字符流。不能传字节流。
            // reader是节点流。br是包装流。
            br = new BufferedReader(reader);// 这个构造方法只能传一个字符流。不能传字节流。*/

            // 合并
            br = new BufferedReader(new InputStreamReader(new FileInputStream("CopyDemo02.java")));

            String line = null;
            while ((line = br.readLine())!= null){
                System.out.println(line);
            }



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

2. 代码——带有缓冲区的字符输出流BufferedWriter

package com.blue.BufferedWriter;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;

/*
BufferWriter:带有缓存的字符输出流
 */
public class BufferedWriterDemo01 {
    public static void main(String[] args) throws Exception{
        //带有缓冲区的字符输出流
//        BufferedWriter out = new BufferedWriter(new FileWriter("copy"));
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("copy",true)));

        // 开始写
        out.write("hello world!");
        out.write("\n");
        out.write("hello world!");
        // 刷新
        out.flush();
        // 关闭最外层
        out.close();

    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-Blue.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值