*其他的流

6 篇文章 1 订阅

目录

一、标准输入、输出流

1.System类的setIn(InputStream is)/setOut(PrintStream ps)

作用

2.例题:从键盘输入字符串,要求读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或“exit”时,退出程序

⚪思路

代码实现

二、打印流

1.作用

2.PrintStream和PrintWriter

 三、数据流

1.作用

2.DataInputStream和DataOutputStream

①DataInputStream中的方法

② DataOutputStream中的方法

3.练习:将内存中的字符串、基本数据类型的变量写出到文件中

4.将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中

⚪注意

四、对象流

1.作用

2.ObjectInputStream和ObjectOutputStream

①序列化

②反序列化

③注意

3.对象的序列化

①对象序列化机制

②好处

③重要性 

④要想一个Java对象是可序列化的,需要满足相应的要求

4.自定义类实现序列化和反序列化操作

①自定义Person类

②Person类需要满足下列要求才可以序列化

 ③Person类的序列化及反序列化

④补充:serialVersionUID

五、随机存取文件流(RandomAccessFile类)

1.概述

2.构造器

3.图片的复制

4.对文件内容的覆盖

①注意

②使用seek()可以从指定部分覆盖

③使用相关操作,实现RandomAccessFile实现数据的插入效果

六、NIO.2中Path、Paths、Files类的使用

1.Java API中提供了两套NIO

①针对标准输入输出NIO

②网络编程NIO

2.Path、Paths和Files核心API

①Path 

② Path常用方法

③Paths

④Files常用方法

​​


一、标准输入、输出流

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

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

1.System类的setIn(InputStream is)/setOut(PrintStream ps)

作用

重新指定输入和输出的流

具体如何使用参考以下例题

2.例题:从键盘输入字符串,要求读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或“exit”时,退出程序

⚪思路

Ⅰ.使用Scanner实现,调用next()返回一个字符串

Ⅱ.使用System.in实现。————>BufferedReader里的readline()

代码实现

    @Test
    public void test1(){
        BufferedReader br = null;
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            br = new BufferedReader(isr);
            while (true){
                String data = br.readLine();
                if(data.equalsIgnoreCase("e") || data.equalsIgnoreCase("exit")){
                    System.out.println("程序结束");
                    break;
                }
                String upperCase = data.toUpperCase();
                System.out.println(upperCase);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

二、打印流

1.作用

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

2.PrintStream和PrintWriter

 三、数据流

1.作用

方便地操作Java语言的基本数据类型和String的数据

2.DataInputStream和DataOutputStream

①DataInputStream中的方法

② DataOutputStream中的方法

将DataInputStream的方法中的read改为write

3.练习:将内存中的字符串、基本数据类型的变量写出到文件中

    @Test
    public void test2() throws IOException {
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
        dos.writeUTF("阿巴阿巴");
        dos.flush();  //刷新操作,将内存中的数据写入文件
        dos.writeInt(23);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();

        dos.close();
    }

4.将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中

⚪注意

读取不同类型的数据的顺序要与当初写入文件时,保存的数据的顺序一致

    @Test
    public void test3() throws IOException {
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
        String name = dis.readUTF();
        int age = dis.readInt();
        boolean b = dis.readBoolean();

        System.out.println(name);
        System.out.println(age);
        System.out.println(b);

        dis.close();
    }

四、对象流

1.作用

存储和读取基本数据类型数据或对象的处理流。其强大之处就是可以把Java中的对象写入到数据中,也能把对象从数据源中还原回来

2.ObjectInputStream和ObjectOutputStream

①序列化

ObjectOutputStream保存基本数据类型数据或对象的机制(将内存中的Java对象保存到磁盘中或通过网络传输出去)

    @Test
    public void test1(){
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
            oos.writeObject(new String("我爱我的祖国"));
            oos.flush();//刷新操作
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

此时的输出: 

因此需要用到反序列化

②反序列化

ObjectInputStream读取基本数据类型数据或对象的机制(将磁盘文件中的对象还原为内存中的一个Java对象)

    @Test
    public void test2(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.txt"));
            Object obj = ois.readObject();
            String str = (String)obj;
            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

③注意

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

3.对象的序列化

①对象序列化机制

允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

②好处

将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可以被还原

③重要性 

④要想一个Java对象是可序列化的,需要满足相应的要求

4.自定义类实现序列化和反序列化操作

①自定义Person类

public class Person {
    private String name;
    private int 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 +
                '}';
    }

    public Person() {
    }

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

②Person类需要满足下列要求才可以序列化

  1. 需要实现接口:Serializable

  2.  当前类提供一个全局常量:serialVersionUID

  3. 除了当前Person类需要实现Serializable接口之外,还必须保证其内部所有属性都是可序列化的(默认情况下,基本数据类型是可序列化的)

 ③Person类的序列化及反序列化

    @Test
    public void test1(){
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
            oos.writeObject(new String("我爱我的祖国"));
            oos.flush();//刷新操作
            oos.writeObject(new Person("张三",25));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Test
    public void test2(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.txt"));
            Object obj = ois.readObject();
            String str = (String)obj;

            Person p = (Person) ois.readObject();

            System.out.println(str);
            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();
                }
            }
        }
    }

④补充:serialVersionUID

serialVersionUID用来表明类的不同版本间的兼容性。其目的就是以序列化对象进行版本控制,有关各版本反序列化时是否兼容

如果类没有显式定义这个静态常量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID可能发生变化,因此建议显式声明

五、随机存取文件流(RandomAccessFile类)

1.概述

①RandomAccessFile声明在java.io包下,但直接继承于java.lang.object类。并且它实现了DataInput、DataOutput两个接口,意味着该类可读可写。

②RandomAccessFile类支持“随机访问”的方式,程序可以直接跳到文件的任意位置来读、写文件

  • 支持只访问文件的部分内容
  • 可以向已存在的文件后追加内容

③RandomAccessFile对象包含一个指针,用以标记当前读写处的位置

④RandomAccessFile类对象可以自由的移动记录指针

  • long getFilePointer():获取文件记录指针的当前位置
  • void seek(long pos):将文件记录指针定位到pos位置

2.构造器

3.图片的复制

    @Test
    public void test1(){
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            raf1 = new RandomAccessFile(new File("1515050201.jpg"),"r");
            raf2 = new RandomAccessFile(new File("1515050201(1).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.对文件内容的覆盖

    @Test
    public void test2(){
        RandomAccessFile raf1 = null;
        try {
            raf1 = new RandomAccessFile("hello.txt","rw");
            raf1.write("xyx".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(raf1 != null){
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

①注意

如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行的过程中自动创建;如果写出到的文件存在,则默认从头覆盖

②使用seek()可以从指定部分覆盖

    public void test2(){
        RandomAccessFile raf1 = null;
        try {
            raf1 = new RandomAccessFile("hello.txt","rw");
            raf1.seek(3);  //将指针调到角标为3的位置
            raf1.write("xyx".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(raf1 != null){
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

③使用相关操作,实现RandomAccessFile实现数据的插入效果

    @Test
    public void test3(){
        RandomAccessFile raf1 = null;
        try {
            raf1 = new RandomAccessFile("hello.txt","rw");
            raf1.seek(3);  //将指针调到角标为3的位置

            //保存指针3后面的所有数据到StringBuilder中
            StringBuilder builder = new StringBuilder((int)new File("hello.txt").length());
            byte[] buffer = new byte[20];
            int len;
            while ((len = raf1.read(buffer)) != -1){
                builder.append(new String(buffer,0,len));
            }
            //调回指针,写入“xyz”
            raf1.seek(3);
            raf1.write("xyx".getBytes());

            //将StringBuilder中的数据写入到文件中
            raf1.write(builder.toString().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(raf1 != null){
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

六、NIO.2中Path、Paths、Files类的使用

Java NIO.2是从Java 1.4版本开始引进的一套新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的,IO是面向流的,基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作

1.Java API中提供了两套NIO

①针对标准输入输出NIO

②网络编程NIO

2.Path、Paths和Files核心API

早期的Java只提供了一个File类来访问文件系统,但File类的功能比较有限,所提供的方法性能也不高。而且,大多数方法在出错时仅返回失败,并不会提供异常信息

①Path 

NIO.2为了弥补这种不足,引入了Path接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。Path可以看成是File类的升级版本,实际引用的资源也可以不存在

② Path常用方法

③Paths

NIO.2在java.nio.file包下还提供了Files、Paths工具类,Files包含了大量静态的工具方法来操作文件:Paths则包含了两个返回Path的静态方法

④Files常用方法

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

elk-zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值