IO流

2022/3/4 23:45:18

本文主要是介绍IO流,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

IO流

文本文件的读操作(FileReader)

/**
 *
 * 一:流的分类:
 * 1.操作数据单位:字节流、字符流
 * 2.数据的流向:输入流、输出流
 * 3.流的角色:节点流、处理流
 *
 * 二、流的体系结构
 * 抽象基类             节点流(或文件流)                                      缓冲流(处理流的一种)
 * InputStream         FileInputStream (read(byte[] buffer))               BufferInputStream (read(byte[] buffer))
 * OutputStream        FileOutputStream  (write(byte[] buffer,0,len))      BufferOutputStream (write(byte[] buffer,0,len) / flush())
 * Reader              FileReader  (read(char[] buffer))                   BufferReader (read(char[] buffer) / readLine())
 * Writer              FileWriter  (write(char[] buffer,0,len))            BufferWriter (write(char[] buffer,0,len) / flush())
 *
 * @author ccchai
 * @create 2022-03-03 10:56
 */
public class FileReaderWriterTest {
​
    /*
    将项目下的hello.txt文件内容读入到程序中,并输入到控制台
​
    说明点:
    1.read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
    2.异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
    3.读入的文件一定要存在,否则就会报FileNotFoundException
     */
    @Test
    public void test1() throws IOException {
        FileReader reader = null;
        try {
            //1.实例化File类的对象,指明要操作的文件
            File file = new File("hello1.txt");
            //2.提供具体的流
            reader = new FileReader(file);
​
            //3.数据的读入
            //read():返回读入的一个字符。如果到达文件末尾,返回-1
            int data;
            while((data = reader.read())!=-1){
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //4.流的关闭操作
                if (reader!=null)
                    reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
​
​
    }
}
//对read()操作升级,使用read的重载方法
    @Test
    public void testFileReader2(){
        FileReader fr = null;
        try {
            //1.File类的实例化
            File file = new File("hello1.txt");
​
            //2.FileReader流的实例化
            fr = new FileReader(file);
​
            //3.读入的操作
            //read(char[] cbuf):返回每次读入cbuf数组中的字符的个数。如果达到文件末尾。返回-1
            char[] cbuf = new char[5];
            int len;
            while((len=fr.read(cbuf))!=-1){
​
                //方式一:
                //错误的写法
//                for (int i = 0; i < cbuf.length; i++) {
//                    System.out.print(cbuf[i]);
//                }
                //正确的写法:
//                for (int i = 0; i < len; i++) {
//                    System.out.print(cbuf[i]);
//                }
                //方式二:
                //错误的写法,对应着方式一的错误的写法
//                String str = new String(cbuf);
//                System.out.print(str);
                //正确的写法
                String str = new String(cbuf,0,len);
                System.out.print(str);
​
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fr!=null)
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
​
    }

文本文件的写操作(FileWriter)

/*
1.输出操作,对应的File可以是不存在的,并不会报异常
2.  File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件
    File对应的硬盘中的文件如果存在:
        如果流使用的构造器是:FileWriter(file,false) / FileWriter(file,true):对原有的文件进行覆盖
        如果流使用的构造器是:FileWriter(file,true): 不会对原有文件覆盖,而是在原文件的基础上追加
 */
@Test
public void testFileWriter(){
    FileWriter fw = null;
    try {
        //1.提供File类的对象,指明写出的文件
        File file = new File("writeTest.txt");
​
        //2.提供FileWriter的对象,用于数据的写入
        fw = new FileWriter(file,true);
​
        //3.写出的操作
        fw.write("hello!\n");
        fw.write("world");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //4.流资源的关闭
        try {
            if (fw!=null)
                fw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
}

文本文件的拷贝操作(FileReader+FileWriter)

@Test
    public void testFileReaderFileWriter(){
        //1.创建File类的对象,指明读入和写出的文件
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //2.创建输入流和输出流的对象
            File srcFile = new File("hello1.txt");
            File destFile = new File("hello2.txt");
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);
​
            //3.数据的读入和写出操作
            char[] cbuf = new char[5];
            int len;//记录每次读入到cbuf数组中的字符的个数
            while((len = fr.read(cbuf))!=-1){
                //每次写出len个字符
                fw.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.关闭流资源
            //方式一
//            try {
//                if (fw!=null)
//                    fw.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//            try {
//                if (fr!=null)
//                    fr.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
​
    }

非文本文件的拷贝操作(FileInputStream+FileOutputStream)

//使用FileInputStream和FileOutputStream对非文本文件进行复制
@Test
public void test(){
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        File srcFile = new File("test.jpg");
        File destFile = new File("test1.jpg");
        fis = new FileInputStream(srcFile);
        fos = new FileOutputStream(destFile);
​
        byte[] bytes = new byte[10];
        int len;
        while ((len = fis.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
​
}

 

非文本文件的拷贝操作(BufferedInputStream+BUfferedOutputStream)

/**
 * 处理流之一:缓冲流的使用
 *
 * 1.缓冲流:
 * BufferInputStream
 * BufferOutputStream
 * BufferReader
 * BufferWriter
 *
 * 2.作用:提高流的读取、写入的速度
 * 提高读写速度的原因:内部提供了一个缓冲区
 *
 * @author ccchai
 * @create 2022-03-04 14:56
 */
public class BufferedTest {
​
    /*
    实现非文本文件的复制
     */
    @Test
    public void BufferedStreamTest(){
​
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1.造文件
            File srcFile = new File("test.jpg");
            File destFile = new File("test2.jpg");
​
            //2.造流
            //2.1 造节点流
            FileInputStream fis = new FileInputStream(srcFile);
            FileOutputStream fos = new FileOutputStream(destFile);
​
            //造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
​
            //3.复制的细节:读取、写入
            byte[] bytes = new byte[10];
            int len;
            while((len = bis.read(bytes))!=-1){
                bos.write(bytes,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源关闭
            //要求:先关闭外层的流,再关闭内层的流
            //说明:关闭外层的流的同时,内层流也会自动的进行关闭,关于内层流的关闭,我们可以省略
            if(bis!=null){
​
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos!=null){
​
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
​
    }
}

转换流(InputStreamReader+OutputStreamWriter)

/**
 * 处理流之二:转换流的使用
 * 1.转换流:属于字符流
 *  InputStreamReader:将一个字节的输入流转换为字符的输入流
 *  OutputStreamWriter:将一个字符的输出流转换为字节的输出流
 *
 * 2.作用:提供字节流和字符流之间的转换
 *
 *
 * @author ccchai
 * @create 2022-03-04 16:31
 */
public class InputStreamReaderTest {
​
    /*
    InputStreamReader的使用,实现字节的输入流到字符的输入流
     */
    @Test
    public void test1(){
        InputStreamReader isr = null;
        try {
            FileInputStream fis = new FileInputStream("hello1.txt");
            //isr = new InputStreamReader(fis);//使用系统默认的字符集
            //参数2指明了字符集,具体使用哪个字符集,取决于文件hello1.txt保存时使用的字符集
            isr = new InputStreamReader(fis,"UTF-8");
​
            char[] cbuf = new char[5];
            int len;
            while ((len = isr.read(cbuf)) != -1){
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (isr!=null)
                    isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
​
    }
}

对象流(重点是序列化和反序列化)

/**
 * 对象流的使用
 * 1.ObjectInputStream 和 ObjectOutPutStream
 * 2.作用:用于存储和读取基本数据类型或对象的处理流。它的强大之处就是可以把java中的对象写入到数据源中,也能把对象从数据源中还原出来。
 *
 * 3.要想一个java对象是可序列化的,需要满足相应的要求。见Person.java
 *
 * 4.序列化机制:
 *   对象序列化机制允许把内存中的java对象转换成与平台无关的二进制流,从而允许把这种
 *   二进制流持久的保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。
 *   当其他程序获取了这种二进制流,就可以恢复成原来的java对象
 *
 * @author ccchai
 * @create 2022-03-04 20:07
 */
public class ObjectInputOutputStreamTest {
​
    /*
    序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
    使用ObjectOutputStream实现
     */
    @Test
    public void testObjectOutputStream(){
​
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("object.bat"));
​
            oos.writeObject(new String("我爱你中国"));
​
            oos.flush();//刷新操作
​
            oos.writeObject(new Person("王阳明",70));
            oos.flush();
​
            oos.writeObject(new Person("王阳明",70,1001,new Account(1000)));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos!=null){
​
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
​
    /*
    反序列化:将磁盘文件中的对象还原为内存中的一个Java对象
    使用ObjectInputStream来实现
     */
    @Test
    public void testObjectInputStream(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.bat"));
            Object object = ois.readObject();
​
            Person p = (Person) ois.readObject();
            Person p1 = (Person) ois.readObject();
            String str = (String) object;
            System.out.println(str);
            System.out.println(p);
            System.out.println(p1);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ois!=null)
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
​
    }
}
/**
 * Person类需要满足如下的要求,方可序列化
 * 1.需要实现接口:Serializable
 * 2.需要提供一个全局常量:serialVersionUID,如果不提供,虽然系统会默认指定一个serialVersionUID,
 *   但当序列化之后修改这个类,再反序列化会报异常InvalidClassException
 * 3.除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性
 *    也必须是可序列化的,(默认情况下,基本数据类型可序列化)
 * 4.ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量
 *
 * @author ccchai
 * @create 2022-03-04 20:24
 */
public class Person implements Serializable {
public static final long serialVersionUID = 65446531254L;

private String name;
private int age;
private int id;
private Account account;

public Account getAccount() {
    return account;
}

public void setAccount(Account account) {
    this.account = account;
}

public Person(String name, int age, int id, Account account) {
    this.name = name;
    this.age = age;
    this.id = id;
    this.account = account;
}

public Person() {
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public Person(String name, int age, int id) {
    this.name = name;
    this.age = age;
    this.id = id;
}

@Override
public String toString() {
    return "Person{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", id=" + id +
            ", account=" + account +
            '}';
}

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 Person(String name, int age) {
    this.name = name;
    this.age = age;
}

}
class Account implements Serializable{

private double balance;

public static final long serialVersionUID = 654465312L;

@Override

public String toString() {

return "Account{" +

"balance=" + balance +

'}';

}
public double getBalance() {
    return balance;
}

public void setBalance(double balance) {
    this.balance = balance;
}

public Account() {
}

public Account(double balance) {
    this.balance = balance;
}

}

RandomAccessFile的使用

  1. RandomAccessFile直接继承于java.lang.Object类,实现类DataInput和DataOutput接口

  2. RandomAccessFile既可以作为一个输入流,又可以作为一个输出流

  3. 如果RandomAccessFile作为输出流时,写出的文件如果不存在,则在执行过程中自动创建

    如果写出的文件存在,则会对原有文件内容进行覆盖。(默认情况下,从头覆盖)



这篇关于IO流的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程