IO 流

IO流

1、什么是IO?

I:Input

O:Output

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

2、IO流的分类?

  • 数据流的流向:输入流、输出流
  • 操作数据单位:字节流(8 bit)、字符流(16 bit)
  • 流的角色:节点流、处理流
抽象基类字节流字符流
输入流InputStreamReader
输出流OutputStreamWriter

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

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

3、文件路径

3.1、路径的分类
  • 相对路径:相较于某个路径下,指明的路径。
  • 绝对路径:包含盘符在内的文件或文件目录的路径。
3.2、路径分隔符
  • windows和DOS系统默认使用两条反斜杠来表示:\
  • UNIX和URL使用"/"来表示:/

4、IO流的四大家族

InputStream 字节输入流

OutputStream 字节输入流

Reader 字符输入流

Writer 字符输出流

  • 都是抽象类

  • 都实现了Closeable接口,都是可关闭的,都有close()方法。

  • 所有的输出流都实现了Flushable接口,都是可刷新的,都有flush()方法。

    输出流在最终输出之后,一定要记得flush()刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是清空管道。

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

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

5、流的体系结构

  • 节点流(或文件流)

    FileInputStream(掌握)

    FileOutputStream(掌握)

    FileReader

    FileWriter

  • 转换流(将字节流转换成字符流)

    InputStreamReader

    OutputStreamWriter

  • 缓冲流

    BufferedReader

    BufferedWriter

    BufferedInputStream

    BufferedOutputStream

  • 数据流

    DataInputStream

    DataOutputStream

  • 标准输出流:

    PrintWriter

    PrintStream(掌握)

  • 对象专属流

    ObjectInputStream(掌握)

    ObjectOutputStream(掌握)

6、FileOutputStream和FileInputStream

FileOutputStream:

​ 文件字节输出流,负责写。

​ 从内存到硬盘。

示例

package IO;

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

public class FileOutputStreamTest01 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            // myfile文件不存在时会自动新建
            // 这种方式谨慎使用,这种方式会先将原文件清空,然后重新写入。
            // fos = new FileOutputStream("myfile");
            // fos = new FileOutputStream("src/IO/hello1");
            // 以追加的方式在文件末尾写入,不清空原文件内容
            fos = new FileOutputStream("src/IO/hello1",true);
            // 开始写
            byte[] bytes = {97,98,99,100};
            // 将byte[]数组全部写出!
            fos.write(bytes);
            // 将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();
                }
            }
        }
    }
}
FileInputStream:

​ 1、文件字节输入流,万能的,任何类型的文件都可以采用这个流来读。
​ 2、字节的方式,完成输入的操作,完成读的操作(硬盘–>内存)
int read(byte[] b)
​ 一次最多读取b.length个字节。
​ 减少硬盘和内存的交互,提高程序的执行效率。
​ 往byte[]数组当中读

示例一

package IO;

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

public class FileInputStreamTest01 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            // 创建文件字节输入流对象
            // 相对路径一定是从当前所在的位置作为起点开始找!
            // IDEA默认的当前路径是哪里?工程Project的根就是IDEA的默认当前路径
            // fis =  fis = new FileInputStream("hello1");
            fis = new FileInputStream("src/IO/hello1");

            /*
            // 开始读
            // 这个方法的返回值是:读取到的字节本身
            int readData = 0;
            while((readData = fis.read())!= -1){
                System.out.println(readData);
            }
             */

            // 准备一个byte数组,一次读取多个字节。最多读取“数组.length”个字节。
            byte[] bytes = new byte[4];
            /*
            while (true){
                // 这个方法的返回值是:读取到的字节数量。(不是字节本身)
                int readCount = fis.read(bytes); // 第一次读到4个字节
                if(readCount == -1){
                    break;
                }
                // 将bytes数组转换成字符串,读到多少个转换多少个
                System.out.println(new String(bytes,0,readCount));
            }
            */
            int readCount = 0;
            while((readCount = fis.read(bytes)) != -1){
                System.out.println(new String(bytes,0,readCount));
            }

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

FileInputStream类的其它常用方法:
int available():返回流当中剩余的没有读到的字节数量
long skip(long n):跳过几个字节不读

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

public class FileInputStreamTest02 {
    public static void main(String[] args){
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("src/IO/hello1");
            System.out.println("总字节数量:" + fis.available());
            // 读1个字节
            // int readByte = fis.read();
            // 还剩下可以读的字节数量是:5
            System.out.println("剩下多少个字节没有读:" + fis.available());
            // 这个方法有什么用?
            byte[] bytes = new byte[fis.available()];  // 这种方式不适合太大的文件,因为byte[]数组不能太大
            // 不需要循环了。
            // 直接读一次就行了。
            int readCount = fis.read(bytes);   // 6
            System.out.println(new String(bytes));  // abcdef

            // skip跳过几个字节不读取,这个方法可能以后会用!
            fis.skip(3);
            System.out.println(fis.read());   // 注释掉上面的读取,输出结果100
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

7、文件复制

使用FileInputStream + FileOutputStream完成文件的拷贝
拷贝的过程应该是一边读,一边写。
使用以上的字节流拷贝文件的时候,文件类型随意,万能的。什么样的文件都能拷贝。

示例

package IO;

import java.io.*;

public class Copy01 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            // 创建一个输入流对象
            fis = new FileInputStream("C://aaa/1.txt");
            // 创建一个输出流对象
            fos = new FileOutputStream("F://ddd/1.txt");

            // 最核心的:一边读,一边写
            byte[] bytes = new byte[1024 * 1024]; // 1MB(一次最多拷贝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();
                }
            }
        }
    }
}

8、FileWriter和FileReader

使用FileReader FileWriter进行拷贝的话,只能拷贝“普通文本”文件。

示例

package IO;

import java.io.*;

public class Copy02 {
    public static void main(String[] args) {
        FileReader in = null;
        FileWriter out = null;
        try {
            // 读
            in = new FileReader("src/IO/Copy02.java");
            // 写
            out = new FileWriter("Copy02.java");

            // 一边读一边写
            char[] chars = new char[1024 * 512];  // 1MB
            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();
        }

    }
}

9、复制普通文本文件

10、带有缓冲区的字符流

11、节点流和包装流

10、带有缓冲区的字符输出流

反序列化:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值