IO流7、IO流_标准的输入输出流、打印流、数据流

其他流的使用

  1. 标准的输入流、输出流
  2. 打印流
  3. 数据流

一、标准的输入流、输出流

  1. System.in:标准的输入流,默认从键盘输入

    System.out:标准的输出流,默认从控制台输出

  2. System类的setIn(InputStream is) / setOut(PrintStream ps)方式重新指定输入和输出的流

/*
从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序。
方法一:使用Scanner实现,调用next()返回一个字符串
方法二:使用System.in实现   System.in ---> 转换流 ---> BufferedRead的ReadLine()
 */
public static void main(String[] args) {
    BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(System.in));

        while (true){
            System.out.println("请输入字符串:");
            String data = br.readLine();
            if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)){
                System.out.println("程序结束!");
                break;
            }
            String newData = data.toUpperCase();
            System.out.println(newData);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (br != null) {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

二、打印流:PrintStream 和 PrintWriter

实现将基本数据类型的数据格式转化为字符串输出

/*
打印流
 */
@Test
public void test1(){
    PrintStream ps = null;
    try {
        FileOutputStream fos = new FileOutputStream(new File("printStream.txt"));
        // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
        ps = new PrintStream(fos, true);
        if (ps != null) {// 把标准输出流(控制台输出)改成文件
            System.setOut(ps);
        }

        for (int i = 0; i <= 255; i++) { // 输出ASCII字符
            System.out.print((char) i);
            if (i % 50 == 0) { // 每50个数据一行
                System.out.println(); // 换行
            }
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (ps != null) {
            ps.close();
        }
    }

}

三、数据流:DataInputStream 和 DataOutputStream

操作Java语言的基本数据类型String的数据

/*
数据流

练习:将内存中的字符串、基本数据类型的变量写出到文件中
 */
//写入
@Test
public void test2(){

    DataOutputStream dos = null;
    try {
        dos = new DataOutputStream(new FileOutputStream("dataStream.txt"));

        dos.writeUTF("张三");
        dos.flush();    //刷新操作,将内存中的数据写入文件
        dos.writeInt(23);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dos != null) {
            try {
                dos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
/*
将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中
注意点:读取不同类型的数据的顺序要与当初写入文件时,保存的数据顺序一致!
 */
//读取
@Test
public void test3(){
    DataInputStream dis = null;
    try {
        dis = new DataInputStream(new FileInputStream("dataStream.txt"));

        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMan = dis.readBoolean();

        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("isMan = " + isMan);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dis != null) {
            try {
                dis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

四、对象流:ObjectInputStream 和 ObjectOutputStream

作用:用于存储和读取基本数据类型数据对象的处理流

序列化机制:允许把内存中的Java对象转换成平台无关的二进制流,从 而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传 输到另一个网络节点。

序列化:用ObjectOutputStream类保存基本类型数据或对象的机制

反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去,使用ObjectOutputStream实现

序列化:

//序列化!
@Test
public void testObjectOutputStream(){
    ObjectOutputStream oos = null;
    try {
        oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
        oos.writeObject(new String("中华人民共和国!"));
        oos.flush();

        oos.writeObject(new Person("李四", 23));
        oos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (oos != null) {
            try {
                oos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

反序列化:

//反序列化:将磁盘文件中的对象还原为内存中的一个java对象
@Test
public void testObjectInputStream(){
    ObjectInputStream ois = null;
    try {
        ois = new ObjectInputStream(new FileInputStream("object.dat"));
        Object obj = ois.readObject();
        String str = (String) obj;
        System.out.println(str);

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

    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        if (ois != null) {
            try {
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Person类

/*
Person类需要满足如下要求,才能序列化
1、需要实现接口:Serializable
2、需要当前类提供一个全局常量:serialVersionUID
3、除了当前类需要实现Serializable接口之外,还必须保证其内部所有属性也必须时可序列化的(默认情况下,基本数据类型可序列化)
 */
public class Person implements Serializable {
    public static final long serialVersionUID = 3928642937452L;

    private String name;
    private int age;

    public Person() {
    }

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

    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;
    }

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

注:ObjectInputStream 和 ObjectOutputStream不能序列化static和transient修饰的成员变量

五、随机存取文件流:RandomAccessFile

RandomAccessFile的使用

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

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

  3. 如果RandomAccessFile作为输出流时,写出的文件如果找不到,则在执行过程中自动创建;写出的文件如果存在,则会对原有文件内容进行覆盖(默认情况下,从头覆盖)

    @Test
    public void testRandomAccessFile(){
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            raf1 = new RandomAccessFile(new File("Default.jpg"), "r");
            raf2 = new RandomAccessFile(new File("Default_raf.jpg"), "rw");
    
            byte[] buffer = new byte[1024];
            int len;
            while ((len = raf1.read(buffer)) != -1){
                raf2.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf1 != null) {
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (raf2 != null) {
                try {
                    raf2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  4. 可以通过相关的操作,实现RandomAccessFile“插入”数据的效果

    /*
    使用RandomAccessFile实现插入效果
     */
    @Test
    public void test3(){
        RandomAccessFile raf1 = null;
        try {
            raf1 = new RandomAccessFile("randomAccess.txt", "rw");
            raf1.seek(22);
    
            //保存指针22后面的所有数据到StringBuilder中
            StringBuilder builder = new StringBuilder((int) new File("randomAccess.txt").length());
            byte[] buffer = new byte[20];
            int len;
            while ((len = raf1.read(buffer)) != -1){
                builder.append(new String(buffer, 0, len));
            }
    
            //调回指针,写入数据
            raf1.seek(22);
            raf1.write("me!".getBytes());
    
            //将StringBuilder中的数据写入到文件中
            raf1.write(builder.toString().getBytes());
    
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (raf1 != null) {
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
posted @ 2021-11-19 23:58  叁玖贰拾柒  阅读(190)  评论(0)    收藏  举报