基本IO操作

本文详细介绍了Java中的基本IO操作,包括节点流和处理流的概念。节点流是直接与数据源或目的地关联的流,如文件流;处理流是对已有流的封装,用于数据的加工处理。示例代码展示了如何使用FileInputStream和FileOutputStream进行文件读写,以及如何使用缓冲流提高效率。此外,还讨论了对象流的序列化和反序列化操作。
摘要由CSDN通过智能技术生成

基本IO操作

节点流和处理流

节点流:可以从或向一个特定的地方(结点读取数据)

处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写

import java.io.*;

/**
 * java标准的IO,可以利用相同的读写方式不同的设备。
 * java将IO比喻为"流",可以理解为是连接程序与设备之间的"管道",管道
 * 里面是按照一个方向顺序流动的字节。
 *
 * java将流的方向划分为两个操作
 * 输入:用来读取,是从设备到程序的方向,是获取的数据使用的。
 * 输出:用来写出,是从程序到设备的方向,用来发送数据使用的。
 *
 * java.io.InputStream是所有字节输入流的超类,里面定义了读取字节的方法
 * java.io.OutputStream是所有字节输出流的超类,里面定义了写出字节的方法
 *
 * java将流分为两类:节点流和处理流
 * 节点流:也称低级流,是实际连接程序与设备的管道,负责实际读取字节的流。
 *       读写一定是建立在节点流的基础上进行的,操作不同的设备有对应的低级流。例如读写文件有文件流。
 * 处理流:也称高级流,不能独立存在,必须连接在其他流上,目的是当数据"流经"当前流时对其做某些加工处理
 *       简化我们的操作。
 * 实际开发中我们总是会串联一组高级流最终连接到低级流上,在数据进行读写的
 * 过程中对数据做流水线式的加工处理,这也成为流连接,也是IO的精髓。
 *
 * 文件流
 * 文件流是一对低级流,用于读写文件的流,功能上与RandomAccessFile一致
 * java.io.FileInputStream和FileOutputStream
 */
public class FOSDemo {
    public static void main(String[] args) throws IOException {
        /*
           文件输出流构造方法:
           FileOutputStream(String path)
           FileOutputStream(File file)
           以上两种构造器创建的文件流为覆盖写模式
           即:创建文件流时如果指定的文件已经存在,则会将该文件内容清空。
           然后使用这个流写出的数据会顺序写入文件作为新数据保存。
           注:RAF则是从头开始写多少覆盖多少。(在不操作指针的情况下)

           文件流重载的构造方法
           FileOutputStream(String path,boolean append)
           FileOutputStream(File file,boolean append)
           如果第二个参数指定,并且指定的值为true时,则当前文件流为
           追加模式。即:创建文件流时如果文件存在,那么文件原有数据保留
           通过这个流写入的数据都会被追加到文件中。
         */
        FileOutputStream fos = new FileOutputStream("fos.txt");
        String line = "我能习惯远距离";
        byte[] data = line.getBytes("UTF-8");
        fos.write(data);

        line = "多远都要在一起";
        fos.write(line.getBytes("UTF-8"));

        System.out.println("写出完毕");
        fos.close();
    }
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * 使用文件输入流读取文件数据
 */
public class FISDemo {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("fos.txt");
        byte[] data = new byte[1000];
        int len = fis.read(data);
        System.out.println("实际读取了"+len+"字节");

        /*
           将给定的字节数组从下表offset处的连续len个字节按照UTF-8
           编码转换为字符串。
         */
        String line = new String(data,0,len,"UTF-8");
        System.out.println(line);
        System.out.println(line.length());

        fis.close();
    }
}
/**
 * 使用文件流完成文件的复制操作
 */
public class CopyDemo {
    public static void main(String[] args) throws IOException {
        /*
           1.创建文件输入流读取原文件
           2.创建文件输出流写入复制文件
           3.循环块读写完成复制
           4.关闭两个流
         */
        FileInputStream fis = new FileInputStream("fos.txt");
        FileOutputStream fos = new FileOutputStream("fos_cp.txt");
        int len;
        byte[] data = new byte[1024*10];
        while((len = fis.read(data))!=-1){
            fos.write(data,0,len);
        }
        System.out.println("复制完毕");
        fis.close();
        fos.close();
    }
}
/**
 * 使用缓冲流完成文件复制。
 *
 * 缓冲流:java.io.BufferedInputStream和BufferedOutputStream
 * 它们是一对高级流,在流连接中的作用是提高读写效率。
 */
public class CopyDemo2 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("love.jpg");
        BufferedInputStream bis = new BufferedInputStream(fis);

        FileOutputStream fos = new FileOutputStream("love_3.jpg");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int d;
        long start = System.currentTimeMillis();
        /*
           缓冲流内部维护着一个字节数组,默认为8k。无论我们读写时用哪种方式,
           最终都会被缓冲流转化为块读写8k8k的进行来保证读写效率。
         */
        while((d = bis.read())!=-1){
            bos.write(d);
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕,耗时"+(end-start)+"ms");
        bis.close();
        bos.close();
    }
}
/**
 * 使用缓冲输出流写出数据的缓冲区问题
 */
public class BOS_flushDemo {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("bos.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        String line = "让我再看你一眼,从南到北。";
        byte[] data = line.getBytes("UTF-8");
        bos.write(data);
        /*
           void flush()
           将缓冲流中已经缓存的数据一次性写出。
           频繁的调用flush会增加实际写出数据的次数,写出次数
           多则写出效率差。但是可以提高写出数据的即时性。
         */
        bos.flush();
        System.out.println("写出完毕!");
        /*
           缓冲流的close方法中会执行一次flush
         */
        bos.close();
    }
}
/**
 * 使用当前类测试对象流的对象读写操作
 *
 * 当一个类的实例希望被对象流进行读写时,该类必须实现接口:
 * java.io.Serializable
 *
 * Serializable接口中没有任何抽象方法,这是一个签名接口,该接口是编译器
 * 敏感的结构,当编译器编译一个类时如果这个类实现了序列化接口则会在编译后
 * 的class文件中添加一个方法,作用是按照该类结构转换为一组字节(对象流就是依靠
 * 这个方法做对象序列化的)
 */
public class Person implements Serializable {
    private String name;
    private int age;
    private String gender;
    /*
       transient关键字可以在对象序列化时忽略该属性的值
       忽略不重要的属性可以达到对象序列化时的瘦身操作,减少资源开销
     */
    private  transient String[] otherInfo;

    public Person(String name, int age, String gender, String[] otherInfo) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.otherInfo = otherInfo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String[] getOtherInfo() {
        return otherInfo;
    }

    public void setOtherInfo(String[] otherInfo) {
        this.otherInfo = otherInfo;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", otherInfo=" + Arrays.toString(otherInfo) +
                '}';
    }
}
/**
 * 将Person对象写入文件
 *
 * 对象流:java.io.ObjectOutputStream和ObjectInputStream
 * 对象流是一种高级流,作用是进行对象的序列化与反序列化
 */
public class OOSDemo {
    public static void main(String[] args) throws IOException {
        String name = "亚索";
        int age = 26;
        String gender = "男";
        String[] otherInfo = {"是一个英雄","来自艾欧尼亚","促进快乐","快乐风男"};
        Person person = new Person(name,age,gender,otherInfo);

        FileOutputStream fos = new FileOutputStream("person.obj");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        /*
           对象输出流提供了一个独有的方法:
           void writeObject(Object obj)
           该方法可以将给定的对象按照其结构转化为一组字节后写出。
           需要注意,该方法要求写出的对象必须实现了序列化结构,
           否则会抛出异常,java.io.NotSerializableException
           
           将一个对象按照其结构转换为一组字节的过程称为对象序列化
           反之则称为对象反序列化
         */
        oos.writeObject(person);
        System.out.println("对象写出完毕!");
        oos.close();
    }
}
/**
 * 对象输入流
 */
public class OISDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //读取person.obj文件中的Person对象
        FileInputStream fis = new FileInputStream("person.obj");
        ObjectInputStream ois = new ObjectInputStream(fis);
        /*
           对象输入流提供的readObject方法可以将读取的字节还原为
           对应的java对象,前提是读取的字节应当是对象输出流将一个
           对象转换的一组字节。返回时统一一Object类型返回,因此
           接收到该对象后要造型。
         */

        Person p = (Person)ois.readObject();
        System.out.println(p);

        ois.close();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值