JavaSE进阶561-581 IO流(一)流的四大家族

开始时间2020-11-22

IO流

1.Io流,什么是Io?
I: Input
o : output
通过Io可以完成硬盘文件的读和写。
这在其他语言中也经常有,参考一下自己之前写的Python的文件读写
以及VBA的文件读写
2.Io流的分类?

按照流的方向进行分类:
以内存作为参照物,往内存中去,叫做输入(Input)。或者叫做读(Read) .
从内存中出来,叫做输出(output)。或者叫做写(write).

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

假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读: 'a’字符('a’字符在windows系统中占用1个字节。)第二次读:'中字符('中’字符在windows系统中占用2个字节。)

假设文件file1.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到a
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。

char在Java中是两个字节,但是在Windows中占用一个字节

Java中所有的流都在Java.io.*下
主要研究:
new流文件
调用流对象是读还是写
主要有四大家族:

  • InputStream
  • OutputStream
  • BufferedReader
  • BufferedWriter

类名以Stream的都是字节流
以Reader/Writer结尾的为字符流
这四种都是抽象类
所有流都实现了Java.io.Closeable接口,都是可关闭的,都有close()方法
用完都要关,这和其他语言也是一样的。
所有输出流都实现了
Java.io.flushable接口,都是可刷新的,都有flush()方法
刷新的作用就是把未输出的数据强行输出完(清空管道)
常用的流:

  • 文件流
  • java.io.FileInputstream
  • java.io.Fileoutputstream
  • java.io.FileReader
  • java.io.Filewriter
  • 转换流(将字节流转为字符流):
  • java .io.InputstreanReader
  • 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

读取示例FileInputStream

package BUPT20201122;

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

/*
 Java.io.FileInputStream
 */
public class IOStreamTest01 {
    public static void main(String[] args) throws FileNotFoundException {
        //创建输入流对象
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream("E:\\编程学习\\Java学习\\Java代码学习\\Java代码.txt");
            int readDate = fileInputStream.read();
            int readDate2 = fileInputStream.read();
            //返回值是读取到的字节本身
            System.out.println(readDate);
            //往后面移动了一位
            System.out.println(readDate2);
            //读到最后会返回-1
            int readDate3;
            while ((readDate3 = fileInputStream.read()) != -1) {
                System.out.println(readDate3);
            }

            //这里也有异常,需要抛一下
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                //关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}

上述代码每次只读了一个字符,这样效率低,改为用数组读,一次多个字符

package BUPT20201122;

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

/*
int read(byte[] b);
一次最多读取b.length个字节
减少硬盘和内存的交互,提高程序的执行效率
 */
public class IOStreamTest02 {
    public static void main(String[] args) throws FileNotFoundException {
        //创建输入流对象
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("20201109/src/BUPT20201122/Java");
            //IDEA工程Project目录的根就是默认当前路径
            byte[] bytes = new byte[15];
            //返回的是字节读的数量,不是字节本身
            int readCount = fis.read(bytes);
            //如果把这一块输出,那么会接着读,一直读到末尾,
            //第一次返回整个byte数组的数量
            //第二次就返回剩下没读完的一口气读完
            //第三次就返回-1
            //但是如果要给他转为String进行输出,那么第一次会读进去的15个都输出
            //但第二次是把读到的4个覆盖数组中的前四个元素//
            //后面的还是之前那15个里面的后11个
            //这并不是我们期待的,应该是读多少个就转多少个
            //因此要传一个起始位置和偏移量
            System.out.println(readCount);
            System.out.println(new String(bytes));
            System.out.println(new String(bytes, 0, fis.read(bytes)));
            System.out.println(fis.read(bytes));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                //关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


这样还是不太完美,改为循环来完成

package BUPT20201122;

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

public class IOStreamTest02 {
    public static void main(String[] args) throws FileNotFoundException {
        //创建输入流对象
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("20201109/src/BUPT20201122/Java");
            byte[] bytes = new byte[15];
            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) {
                //关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

两种常用的方法 skip和available

package BUPT20201122;

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

public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream("20201109/src/BUPT20201122/Java");
            //返回剩下没有读到的字节数量
            /*
            System.out.println(fileInputStream.available());
            //有多少要读,直接一步到位,不用写循环,这种方式不太适合大文件
            byte[] bytes = new byte[fileInputStream.available()];
            int readCount = fileInputStream.read(bytes);
            System.out.println(new String(bytes));
             */

            //skip方法,跳过几个字节不读取
            fileInputStream.skip(3);
            System.out.println(fileInputStream.read());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                //关闭流的前提是流不为空,流是null没必要关闭,避免空指针异常
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileOutputStream

package BUPT20201122;

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

public class FileOutputStreamTest01 {
    public static void main(String[] args) throws FileNotFoundException {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream("Jindaohei.txt", true);
            //写完之后一定要记得刷新
            byte[] bytes = {97, 101, 110, 113};
            //写入了文件里,没有文件就自动新建,有的话就清空再写
            // 但如果在FileOutputStream中append参数为true,则表示追加
            fileOutputStream.write(bytes);
            fileOutputStream.write(bytes, 0, 2);
            String s = "这是一段字符串";
            //转一下类型
            byte[] bytes1 = s.getBytes();
            fileOutputStream.write(bytes1);
            fileOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }


    }
}

文件的复制

package BUPT20201129;

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

/*
使用FileInputStream和FileOutputStream完成文件的拷贝
一边读,一边写,使用字节流,什么类型文件都能拷
 */
public class Copy01Test {
    public static void main(String[] args) throws IOException {
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            //创建输入流对象
            fileInputStream = new FileInputStream("E:\\研一\\4_20201019_光纤的损耗、色散、光的调制.mp4");
            //创建输出流对象
            fileOutputStream = new FileOutputStream("D:\\4_20201019_光纤的损耗、色散、光的调制.mp4");
            //一边读,一边写,一次拷贝1MB
            byte[] bytes = new byte[1024 * 1024];
            int readCount = 0;
            //读多少写多少
            while ((readCount = fileInputStream.read(bytes)) != -1) {
                fileOutputStream.write(bytes, 0, readCount);
            }
            //记得刷新
            fileOutputStream.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //分开用try,不然可能影响到另一个的关闭
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

FileReader

package BUPT20201129;

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

/*
FileReader读取文本的字符输入流

 */
public class FileReaderTest {
    public static void main(String[] args) {
        FileReader fileReader = null;
        try {
            fileReader = new FileReader("Java代码.txt");
            //一次读四个char
            char[] chars = new char[4];
            int readCount = 0;
            while ((readCount = fileReader.read(chars)) != -1) {
                System.out.print(new String(chars, 0, readCount));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

FileWriter

package BUPT20201129;

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

/*
FileWriter文件字符输出流,只能输出普通文本
 */
public class FileWriterTest {
    public static void main(String[] args) {
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter("Java代码.txt", true);
            char[] chars = {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
            fileWriter.write(chars);
            fileWriter.write(chars, 2, 3);
            fileWriter.write("你好");
            fileWriter.write("\n这里换行了");
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileWriter != null)
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
}

FileReader和FileWriter完成复制粘贴

package BUPT20201129;

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

/*
FileRead/FileWriter执行拷贝普通文本文件
 */
public class Copy02 {
    public static void main(String[] args) {
        FileReader in = null;
        FileWriter out = null;
        try {
            in = new FileReader("Java代码.txt");
            out = new FileWriter("Java代码2.txt");
            //一个char两个bit,这里就是一兆
            char[] chars = new char[1024 * 512];
            int readCount = 0;

            while ((readCount = in.read(chars)) != -1) {
                out.write(chars, 0, readCount);
            }
            out.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

带缓冲区的流

BufferedReader

package BUPT20201130;

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

public class BufferedReaderTest {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("F:\\编程学习\\Java学习\\学习啊.txt");
        //传参直接传的是reader,但reader是一个抽象类,FileReader是他的子类
        //当一个流的参数为流时,被传进来的流称为节点流,外部负责包装的叫包装流(处理流)
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        //读取一行
        String FirstLine = bufferedReader.readLine();
        System.out.println(FirstLine);
        //关闭只需要关包装流就行
        String s = null;
        //读的一行不包括换行符
        while ((s = bufferedReader.readLine()) != null) {
            System.out.println(s);
        }
        bufferedReader.close();
    }
}

节点流和包装流

package BUPT20201130;

import java.io.*;

public class BufferedReadTest02 {
    public static void main(String[] args) throws IOException {
        //字节流
        FileInputStream fileInputStream = new FileInputStream("F:\\编程学习\\Java学习\\学习啊.txt");
        //字节流转为字符流
        InputStreamReader reader = new InputStreamReader(fileInputStream);
        //一次只能传一个字符流
        BufferedReader bufferedReader = new BufferedReader(reader);

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

package BUPT20201130;

import java.io.*;

/*
BufferedWriter:带有缓冲的字符输出流
OutPutStreamWriter:转换流
 */
public class BufferedWriterTest01 {
    public static void main(String[] args) throws IOException {
        //写一个新的文本文件
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("F:\\编程学习\\Java学习\\学习啊2.txt"));
        //字节变字符,再传参
        BufferedWriter bufferedWriter1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("F:\\编程学习\\Java学习\\学习啊3.txt")));
        bufferedWriter.write("hello Java\n");
        bufferedWriter.write("This is a Java Program");
        bufferedWriter1.write("hello Java\n");
        bufferedWriter1.write("This is a Java Programming");
        bufferedWriter1.flush();
        bufferedWriter1.close();
        bufferedWriter.flush();
        bufferedWriter.close();
    }


}

结束时间:2020-11-30

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值