IO__总

IO

什么是流(Stream)?

  • 内存与存储设备之间传输数据的通道。
  • 数据借助流传播。

流的分类

按方向划分

  • 输入流:将存储设备中的内容读入到内存中
  • 输出流:将内存中的内容写入到存储设备中

按单位划分

  • 字节流:以字节为单位,可以读写所有数据
  • 字符流:以字符为单位,只能读写文本数据

按功能划分

  • 节点流:具有实际传输数据的读写功能。
  • 过滤流:在节点流的基础之上增强功能。

字节流抽象类

  • 字节流的父类(抽象类)
  1. InputStream
  • 字节输入流的所有类的超类。
  1. OutputStream
  • 这个抽象类是表示字节输出流的所有类的超类。 输出流接收输出字节并将其发送到某个接收器。

FileInputStream

构造方法
  • FileInputStream(File file)
    通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
  • FileInputStream(FileDescriptor fdObj)
    创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
  • FileInputStream(String name)
    通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
常用方法
read()

public int read()
功能:从输入流读取数据的下一个字节。若已经到达流的末尾,返回值是 -1 。

    public static void main(String[] args) throws IOException {
        System.out.println("----------单个字节读取-----------");
        FileInputStream filIn = new FileInputStream("D:\\JavaCode\\JavaSE\\zz.txt");//括号内为文件的地址
        int date = 0;
        while ((date = filIn.read())!= -1){ //若已经到达流的末尾,返回值是 -1 
            System.out.print((char) date);
        }
        filIn.close();
----------单个字节读取-----------
xyzabcdef
Process finished with exit code 0
read(byte[] b)

public int read(byte b[])
功能:从输入流读取一些字节数,并将它们存储到缓冲区 b 。

    public static void main(String[] args) throws IOException {
        System.out.println("----------一次性多个字节读取-----------");
        FileInputStream filIn = new FileInputStream("D:\\JavaCode\\JavaSE\\zz.txt");
        byte[] b = new byte[6]; //byte的长度为缓存区
        int count = filIn.read(b);   //返回值为读取长度
        System.out.println(new String (b)); //将 byte型数组b 转为 String型
        System.out.println("读取的长度为:"+count);
        int count2 = filIn.read(b);
        System.out.println(new String (b));
        System.out.println("读取的长度为:"+count2);
        filIn.close();
----------一次性多个字节读取-----------
xyzabc
读取的长度为:6
defabc
读取的长度为:3

Process finished with exit code 
  • 通过输出可以发现结果是覆盖的,我们可以在转String的时候仅输出有效的部分,上可修改为System.out.println(new String (b,0,count2));
read(byte[] b, int off, int len)

public int read(byte b[], int off, int len)
功能:从输入流在 off 位置开始读取最多 len字节的数据到一个字节数组。

    public static void main(String[] args) throws IOException {
        System.out.println("----------使用read(byte[] b, int off, int len) -----------");
        FileInputStream filIn = new FileInputStream("D:\\JavaCode\\JavaSE\\zz.txt");
        byte[] b = new byte[8];
        int count = filIn.read(b,2,3);
        System.out.println(new String(b)); //将 byte型数组b 转为 String型
        System.out.println("读取的长度为:"+count);
        filIn.close();
----------使用read(byte[] b, int off, int len) -----------
  xyz   
读取的长度为:3

Process finished with exit code 0

close()

public void close()
功能:关闭此输入流并释放与流相关联的任何系统资源。

FileOutputStream

构造方法
  • FileOutputStream(File file)
    以写入由指定的 File对象表示的文件。
  • FileOutputStream(File file, boolean append)
    以写入由指定的 File对象表示的文件。
  • FileOutputStream(FileDescriptor fdObj)
    以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
  • FileOutputStream(String name)
    以指定的名称写入文件。
  • FileOutputStream(String name, boolean append)
    以指定的名称写入文件 append默认false 即覆盖原文件 为true则在文件内容后追加
常用方法
write(int b)

public void write(int b)
功能:将指定的字节写入此文件输出流。

    public static void main(String[] args) throws Exception{
        FileOutputStream fil = new FileOutputStream("D:\\JavaCode\\JavaSE\\zzz.txt");//不存在则会创建
        int b = 97;
        fil.write(b);
        fil.close();
    }

查看zzz.txt内容

a
write(byte[] b) & write(byte[] b, int off, int len)

public void write(byte b[])
public void write(byte b[], int off, int len)
功能:将 b.length个字节从指定的字节数组写入此文件输出流。
从下标 off 开始写入 len 个数据写入此文件输出流。

    public static void main(String[] args) throws Exception{
        FileOutputStream fil = new FileOutputStream("D:\\JavaCode\\JavaSE\\zzz.txt");//不存在则会创建
        byte[] b = new byte[10];
        b[0] = 13; //ascll码表 13为CR 回车
        b[1] = 14;
        b[2] = 15;
        fil.write(b[1]);
        fil.write(b,0,3);
        fil.close();
    }

查看zzz.txt内容
在这里插入图片描述

其他常用的write() 例子
    public static void main(String[] args) throws Exception{
        FileOutputStream fil = new FileOutputStream("D:\\JavaCode\\JavaSE\\zzz.txt");//不存在则会创建
        fil.write("\r".getBytes());//写入换行 windows使用“\n”或者“\r” Linux "\n" Mac "\r"
        String str = "HelloWorld";
        fil.write(str.getBytes());
        fil.write("\n".getBytes());
        String str1 = "湖南长沙";
        fil.write(str1.getBytes());
        fil.close();
    }

在这里插入图片描述

close()

public void close()
功能:关闭此文件输出流并释放与此流相关联的任何系统资源。

字节流复制文件

步骤
  1. 创建流,输入流,输出流。
  2. 创建 byte[ ] 缓存数据。
  3. 接收读取数量。
  4. 边读边写。
代码示例
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class TestCopy {
    public static void main(String[] args) throws Exception{
        //创建流
        //输入流
        FileInputStream fis = new FileInputStream("E:\\11.png");
        //输出流
        FileOutputStream fos = new FileOutputStream("E:\\22.png");
        //创建缓冲区   1024 -->1K
        byte[] b = new byte[1024];
        //用count来接收读的数量
        int count = 0;
        //边读边写
        while ((count = fis.read(b)) != -1){
            fos.write(b,0,count); //从下标 off 开始写入 len 个数据写入此文件输出流
        }
        fis.close();
        fos.close();
    }
}

BufferedInputStream & BufferedOutputStream

  • 字节缓冲流
  • 提高IO效率,减少访问磁盘次数。内部定义了一个8K的缓冲区,具体查看源码。
  • 数据存储在缓冲区中,flush是将缓存区的内容写入文件,也可以直接close。
  • 方法与FileInputStream & FileOutputStream 相似。
BufferedInputStream构造方法
  • BufferedInputStream(InputStream in)
    创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用。
  • BufferedInputStream(InputStream in, int size)
    创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。
代码示例
import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class TestBufferedInputStream {
    public static void main(String[] args) throws Exception{
        FileInputStream fis = new FileInputStream("D:\\JavaCode\\JavaSE\\zz.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        int date = 0;
        while ((date = bis.read()) != -1){
            System.out.print((char)date);
        }
        bis.close();
    }
}
BufferedOutputStream 构造方法
  • BufferedOutputStream(OutputStream out)
    创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
  • BufferedOutputStream(OutputStream out, int size)
    创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。
代码示例
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

public class TestBufferedOutputStream {
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream("D:\\JavaCode\\JavaSE\\Buffered.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.write("HelloWorld".getBytes());//写入8K缓冲区
        bos.flush();//若不使用flush()方法来刷新硬盘 或者不关闭该字节缓冲流(close方法中执行了flush方法) 该写入仅写至缓冲区
        bos.close();//内部调用了flush方法
    }
}

注意事项:若不使用flush()方法来刷新硬盘 或者不关闭该字节缓冲流(close方法中执行了flush方法) 该写入仅写至缓冲区

对象流

  • ObjectOutputStream(序列化) & ObjectInputStream(反序列化)
  • 增强了缓冲区功能。
  • 增强了读写8种基本数据类型和字符串的功能。
  • 增强了读写对象的功能。
  • readObject() 从流中读取一个对象
  • writeObject() 向流中写入一个对象
  • 使用流传输对象的过程称之为序列化和反序列化
ObjectOutputStream(序列化)
  • 将一个对象写入硬盘。
代码示例

先创建一个对象 序列化的对象需要实现Serializable接口

import java.io.Serializable;

public class Student implements Serializable { //实现Serializable接口
    public static final long serialVersionUID = 100;
    private String name;
    private int age;
    private transient String country;//使用transient(瞬间)修饰的属性不能被序列化
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "name:"+ this.name +"\t"+"age:"+this.age;
    }
}
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class TestObjectOutputStream {
    public static void main(String[] args) throws Exception{
        FileOutputStream fos = new FileOutputStream("D:\\JavaCode\\JavaSE\\stu.bin");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        Student stu1 = new Student("张三",18);
        oos.writeObject(stu1);
        oos.close();
    }
}

注意事项

  • 创建的bin文件只是一个类型,用txt打开会发现是乱码,因为他是一个对象。
ObjectInputStream(反序列化)
  • 从流中读取对象。
代码示例
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class TestObjectInputStream {
    public static void main(String[] args) throws Exception{
        FileInputStream fis = new FileInputStream("D:\\JavaCode\\JavaSE\\stu.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Student stu2 = (Student) ois.readObject();//返回的是一个Object类型 高到低 强制转换为Student类
        ois.close();
        System.out.println(stu2.toString());
    }
}
name:张三	age:18

Process finished with exit code 0
序列化与反序列化的注意事项
  1. 序列化类必须实现Serializable接口。
  2. 序列化类中的对象属性也要求实现Serializable接口。
  3. public static final long serialVersionUID = ***L,序列化版本号ID,保证序列化的类和反序列化的类是同一个类。
  4. 使用 transient(瞬间)修饰的属性不能被序列化。
  5. 静态属性不能被序列化。
  6. 序列化多个对象,可以借助集合实现。

持续更新中…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值