Java学习笔记Java 杂谈

JAVA语言入门教学系列之IO篇

2018-12-20  本文已影响2人  Java丶python攻城狮

本文主要向大家介绍了JAVA语言入门教学系列之IO篇,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

前戏

有很多同学单纯的认为IO不就是一个读文件和写文件吗,不重要,只要简单的复制粘贴就OK,

会用个File以及什么流就算"熟练掌握 "了。

使用场景也就上传文件才用的到,仅此而已。

呵呵呵呵,那就大错特错了,IO的使用范围很广,最能体现IO价值的就是网络上的数据传递,

尤其是进入互联网时代后,各种常见的分布式架构,都少不了IO的体现。

并且很多大厂的面试题中都会体现出对IO的重视,包括衍生出来的NIO、序列化等等。

因此学好IO,变成了一件很重要的事情。

IO基本概念

IO可以简单的理解成INPUT和OUT,代表输入输出的意思。输入就是读,输出就是写。

IO可以读写硬盘、光盘、内存、键盘、网络等资源上的数据。

IO中的流就相当于现实生活中的水流一样,一打开自来水的龙头开关,水就从一头流向另一头。

可以理解成每个按顺序排列的水滴就是需要传输的字节。

把有序数据理解成流,流负责传输数据,以便于输入输出。数据是流动的,是有方向的流动。

流的分类

按数据的走向可以分为:输入流,输出流。

按数据的单位可以分为:字节流、字符流。

按装饰模式可以分为:节点流(底层)、处理流(上层)。

输入流与输出流

输入流:只能从中读取数据,而不能向其写入数据。一般用于将数据从网络、硬盘读取到内存中。

输出流:只能向其写入数据,而不能从中读取数据。一般用于将数据从内存中写入到网络、硬盘。

输入流主要由InputStream和Reader作为父类。

输出流主要由OutputStream和Writer作为父类。

他们都是抽象的,因此无法直接创建对象。

字节流与字符流

字节流与字符流的用法几乎完全一样,区别在于所操作的单位不同,字节流操作8位的字节,

而字符流操作16位的字符。

字节流主要由InputStream和OutputStream作为父类。

字符流主要由Reader和Writer作为父类。

节点流与处理流

节点流(上层):

向特定的节点写入&读取数据的流。程序连接到实际的数据源,和实际的输入输出节点连接。

处理流(底层):

对一个已存在的流进行连接或封装,通过封装后的流来实现数据读写功能。

使用处理流进行输入输出时,程序不会和实际的输入输出节点连接,对底层的处理流做了一层封装。

程序可以采用相同的输入输出代码来访问不同的数据源。(涉及到装饰器模式)

处理流使得java程序无需理会输入输出的节点是磁盘、网络还是其他,

只要将这些节点流包装成处理流,

就可以使用相同的输入输出代码来读写不同的输入输出设备的数据。

节点流用于和底层的物理存储节点直接关联,不同的物理节点获取节点流的方式可能存在差异。

程序可以把不同的物理节点流包装成统一的处理流,

允许程序使用统一的输入输出代码来读写不同的物理存储节点资源。

常用的输入输出流体系

io流按功能分成许多类,每个功能又提供字节流&字符流,

字节流与字符流又分别提供了输入流与输出流。

如果输入输出的是文本内容可以使用字符流,如果输入输出的是二进制内容,可以使用字节流。

字节流

字节流是IO最原始的方式,因为计算机处理数据总是以一个byte为基本单位的,

字节流就是每次读取的单位为byte。字节流是所有流的基础,也是其他高级流的前提。

字节流可以处理所有类型的数据,包括:音乐、图片、文字、视频、各种文件等等。

多数以"Stream"结尾的类都是字节流。

字符流只能处理文本,读写的单位是字符。多数以"Writer"与"Reader"结尾的类都是字节流。

java的基础字节流的类为:InputStream,OutputStream。

通过他们俩可以衍生出许多子类,常见的有:

FileInputStream,FileOutputStream,ObjectInputStream,ObjectOutputStream,BufferedInputStream,BufferedOutputStream等。

byte是计算机最基本的单位,所以字节流可以应付几乎所有的流的处理,只不过,在处理具体数据格式的时候,效率没有具体的实现类高,如字符格式,对象格式等。主要操作对象是byte数组,

通过read()和wirte()方法把byte数组中的数据写入或读出。

使用字节流复制文件

public class FileInputOutStreamDemo1 {

    public static void main(String[] args) {

        FileInputStream fis = null;

        FileOutputStream fos = null;

        try {

            fis = new FileInputStream("enya恩雅-only time.mp3");

            fos = new FileOutputStream("new-enya恩雅-only time.mp3");

            byte[] temp = new byte[1024];

            while(fis.read(temp)!=-1) {

                fos.write(temp);

            }

            temp = new byte[1024];

            //将字符串写入到文件

            fos = new FileOutputStream("aaa.txt");

            fos.write("我爱你亲爱的姑娘".getBytes());//直接覆盖,而不是追加。如果想追加怎么办?

            fis = new FileInputStream("aaa.txt");

            fis.read(temp);

            System.out.println(new String(temp));

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            if(fis!=null) {

                try {

                    fis.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

            if(fos!=null) {

                try {

                    fos.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

        System.out.println("结束");

    }

}

可以理解成把输入数据想象成存储在一个水管当中,

输入流的read()方法从水管中读取一个或多个水滴,

水滴的单位是字节或字符,当使用数组作为读取方法参数时,read(byte []),

这个数组相当于一个竹筒,

使用竹筒去水管中取水,程序重复这个取水的过程,直到read(byte [])返回-1为止。

字符流

针对文本文件,使用字符流来写入和读出字符数据。无需再使用字节流进行包装,

字符流是由字节流包装而来,

它包括:StringReader,StringWriter,BufferedReader,BufferedWriter。

对于前者,他们的使用方法和字节流类似,主要还是read()和wirte(),

而后者多加了一个readLine()方法,用于读取文章类型的文本。

FileReader、FileWriter,节点流,会直接和指定文件相关联。

使用字符流复制文本文件

public class FileWriterDemo1 {

    public static void main(String[] args) {

        FileReader fr = null;

        FileWriter fw = null;

        try {

            char[] temp = new char[1024];

            // 将字符串写入到文件

            fw = new FileWriter("aaa.txt");

            fw.write("我爱你亲爱的姑娘55555");// 直接覆盖,而不是追加。如果想追加怎么办?

            fr = new FileReader("aaa.txt");

            fr.read(temp);

            System.out.println(new String(temp));

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            if (fr != null) {

                try {

                    fr.close();

                } catch (IOException e) {

                    e.printStackTrace();

            }

            if (fw != null) {

                try {

                    fw.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

        System.out.println("结束");

    }

}

字符流对象在创建时,一般需要提供一个输入or输出流。

例如在创建BufferedReader或者BufferedWriter对象时,

需要提供InputStreamReader或OutputStreamWriter对象。

对于特定支付格式的文本内容,还需要在创建的时候提供字符格式类型作为构造参数。

小例子:字符输入流

File f = new File("D:\\VSS存放目录\\KOOF\\3-开发阶段\\3.3-数据库","koof30.sql");

FileReader fi = new FileReader(f);

BufferedReader in = new BufferedReader(fi);

String s ;

String total = "";

while((s=in.readLine())!=null){

total += s+"\n";

}

处理流(上层)与节点流(底层)

处理流隐藏底层设备上节点流的差异,并对外提供更加方便的输入输出方法,

让我们只关心上层流的操作,有点像应用层的感觉。

可以使用处理流来包装节点流,通过处理流执行输入输出功能,

节点流则负责与底层的IO设别、文件交互。

处理流的构造参数不是一个物理节点,而是已经存在的节点流,而节点流的构造参数都是物理节点。

上面的例子都是使用节点流(FileInputStream、FileOutputStream、FileReader、FileWriter)。

在使用节点流过程中比较繁琐,因此我们可以使用处理流。

public class PrintStreamDemo1 {

    public static void main(String[] args) {

        PrintStream ps = null;

        try {

            ps = new PrintStream(new FileOutputStream("bbb.txt"));

           &nb    

最后,如果你跟我一样都喜欢java,想成为一名优秀的程序员,也在学习java的道路上奔跑,欢迎你加入java学习群:72030155 群内每天都会分享java最新业内资料,分享java免费课程,共同交流学习,让学习变(编)成(程)一种习惯!

上一篇下一篇

猜你喜欢

热点阅读