JAVA基础10—流

0.前言

生活中存在水流、电流、车流等流。程序出于生活,程序中也有流。

JAVA中,往往通过流与外部进行数据交换。

我们可以将流理解为连接程序与外部设备之间的管道,管道里流的是字节。

1.流

从方向上对流进行初步的分类:以程序为原点,向文件输出数据的称作输出流OutputStream,读取文件的称为输入流InputStream。

本节介绍常用的流。

1.1 字节流

InputStream 和 OutStream 分别是字节输入、输出流,抽象类。
FileInputStream 和 FileOutputStream 分别继承自InputStream 、 OutputStream ,用于文件的读写。

至于JAVA文件的常用方法以及学习过程中可能遇到的异常处理问题,可参见JAVA基础之文件与异常处理

1.2.1 FileInputStream

作用:读取文件

例子:

     FileInputStream fis = new FileInputStream("./test.txt");
        /**
         * 读取规则,一位一位地读,输出低八位,余位补0,读到末尾返回-1的补码
         * 用基本类型接收的时候,会输出该位的二进制
         * */
        int index = 24;
        while(index > 0 ){
            char d = (char) fis.read();
            System.out.println(d);
            index --;
        }
        fis.close();

1.2.2 FileOutputStream

作用:写入文件

例子:

 //向文件test.txt写入一个字节
        FileOutputStream fos = new FileOutputStream("./test.txt");
        //以程序为原点,要将东西写入文件,使用输出流
        /*
         * void write (int d)
         * 写出一个字节,写出的内容是给定的int值对应的二进制的低八位
         * */
        int index = 26;
        while(index >0){
            fos.write(index+97);
            index --;
        }
        System.out.println("写出完毕");
        
        //流每次用完都需要关闭
        fos.close();

        File f = new File("./test.txt");
        if(f.isFile()){
            System.out.println(f.length());
        }

根据上述例子学习完字节流,可以利用字节流复制文件玩一玩

public class CopyDemo {
    public static void main(String[] args) throws IOException {
        //定义流
        long now = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("./CpDemoPlus.mp4");
        FileOutputStream fos = new FileOutputStream("./CpDemoPlus2.mp4");

        //用比较简洁的方式复制
        int index;
        while ((index = fis.read())!=-1){
            fos.write(index);
        }

        System.out.println("复制完毕!");
        fis.close();
        fos.close();
        long after = System.currentTimeMillis();
        System.out.println("复制经历了"+(after-now)+"ms");
    }
}

在学习字节流的过程中,我们需要注意的是流用完后需要关闭,需要异常处理。

1.2 字符流

流按照处理的单位来分类,可以分为字节流和字符流,顾名思义就是分别以字节、字符为单位处理数据。

字符流的父类分别为Reader字符输入流、Writer字符输出流。

文件的字符流FileReader 和 FileWriter 分别是 Reader、Writer 的子类,我们再次以文件流为例学习

1.2.1 FileReader

    public static void main(String[] args) throws IOException {
		File f = new File("eng.txt");
		FileReader fr = new FileReader(f);
		//读取
		char [] cs = new char[(int) f.length()];
		fr.read(cs);
		for(char r : cs) {
			System.out.println(r);
		}
		fr.close();

1.2.2 FileWriter

        File file = new File("eng.txt");
        // 创建文件
        file.createNewFile();
        FileWriter fw = new FileWriter(file);
        // 向文件写入内容
        fw.write("a\n b\n c\n");
        fw.flush();
        fw.close();

1.3 缓冲流

从流的功能来进行分类,流又可以分为节点流(低级流)、处理流(高级流)。打个现实生活中的比方,我们用水管进行类比,生活中的自来水管可以看作是低级流,那么接在水管上的热水器就可以看作是处理流,是对水管里的水进行处理的,同时,热水器也必须接在水管上。换言之,处理流必须基于节点流来对数据进行处理。

这里先介绍缓冲流。
缓冲流可以在对数据进行读写的时候,会对数据进行缓存处理,达到提高效率的目的。

1.3.1 BufferedReader

    //将当前源代码输出到控制台上
        //建立流连接
        FileInputStream fis = new FileInputStream("./src/io/BRDemo.java");

        //转换流与高级流
        InputStreamReader isr = new InputStreamReader(fis);

        //高级流
        BufferedReader br = new BufferedReader(isr);

        //解决只读取一行的问题
        String line;
        while ((line = br.readLine())!=null){
            System.out.println(line);
        }

1.3.2 PrintWriter

     //用PrintWriter向文件写数据,其中支持自动换行
        PrintWriter pw = new PrintWriter("PWD.txt","utf-8");
        pw.println("喜羊羊美羊羊");
        pw.println("喜羊羊美羊羊*2");

        System.out.println("写出完毕");
        pw.close();
    }

注意,上面的代码例子只是省略了连接低级流的过程,实际上PrintWriter可以进行手动流连接

 //如果要追加模式,在第一层的文件流里写
        FileOutputStream fos = new FileOutputStream("pw2.txt",true);

        OutputStreamWriter osw = new OutputStreamWriter(fos);

        BufferedWriter bw = new BufferedWriter(osw);

        PrintWriter pw = new PrintWriter(bw);

        pw.println("您好!");

        System.out.println("写出完毕");

        pw.close();

1.4 对象流

对象流也是一种处理流,将一个对象以流的形式进行传输,即将一个对象进行序列化与反序列化。

1.4.1 序列化

/**实现序列化接口*/
public class Person implements Serializable {
                             
    /**版本号,解决反序列化过程中对象版本不一致的问题*/
    public static final long serialVersionUID = 1L;

    /**定义属性*/
    private String name;
    private int age ;
    private String gender;

    private transient String [] otherInfo;
        String name = "喜羊羊";
        int age = 6;
        String gender = "公";
        String[] otherInfo = {"HelloWorld","123"};

        //创建对象
        Person p = new Person(name,age,gender,otherInfo);

        //对象流
        FileOutputStream fos = new FileOutputStream("person.obj");
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        //将对象写进去

        oos.writeObject(p);
        System.out.println("写出完毕");

        oos.close();

    }

1.4.2 反序列化

    FileInputStream fis = new FileInputStream("person.obj");
        ObjectInputStream ois = new ObjectInputStream(fis);

        Person person = (Person)ois.readObject();
        System.out.println(person);
        ois.close();

2.总结

本文我们学习了JAVA中常见的流的基本用法。流从方向上分为输入流、输出流;从处理的数据上,分为字节流、字符流;从功能上分,又分为节点流(低级流)、处理流(高级流)。每种流我们都选取了一些例子进行学习,学习过程中,需要注意异常处理、流的关闭以及高级流的嵌套关系。

希望对读者有所帮助。下一篇文章见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值