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

本文主要向大家介绍了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流按功能分成许多类,每个功能又提供字节流&字符流,
字节流与字符流又分别提供了输入流与输出流。
如果输入输出的是文本内容可以使用字符流,如果输入输出的是二进制内容,可以使用字节流。

分类	字节输入流	字节输出流	字符输入流	字符输出流抽象父类	InputStream	OutputStream	Reader	Writer访问文件?(节点流 )	FileInputStream	FileOutputStream	FileReader	FileWriter访问数组?(节点流 )	ByteArrayInputStream	ByteArrayOutputStream	CharArrayReader	CharArrayWriter访问管道?(节点流)	PipedInputStream	PipedOutputStream	PipedReader	PipedWriter访问字符串?(节点流 )	?	?	StringReader	StringWriter缓冲流	BufferedInputStream	BufferedOutputStream	BufferedReader	BufferedWriter转换流	?	?	InputStreamReader	OutputStreamWriter对象流	ObjectInputStream	ObjectOutputStream	?	?过滤器流	FilterInputStream	FilterOutputStream	FilterReader	FilterWriter打印流	?	PrintStream	?	PrintReader推回输入流	PushbackInputStream	?	PushbackReader	?特殊流	DataInputStream	DataOutputStream	?	?

字节流
字节流是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:0}}");// 直接覆盖,而不是追加。如果想追加怎么办?
        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免费课程,共同交流学习,让学习变(编)成(程)一种习惯!

猜你喜欢

转载自blog.csdn.net/qq_28263265/article/details/85117143