Java基础14.IO流

IO流

IO流,什么是IO?

​ I : Input
​ O : Output
​ 通过IO可以完成硬盘文件的读和写。

IO流的分类?

有多种分类方式:

	一种方式是按照流的方向进行分类:
		以内存作为参照物,
			往内存中去,叫做输入(Input)。或者叫做读(Read)。
			从内存中出来,叫做输出(Output)。或者叫做写(Write)。

	另一种方式是按照读取数据方式不同进行分类:
		有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位。
		这种流是万能的,什么类型的文件都可以读取。包括:文本文件,图片,声音文件,视频文件等....
			假设文件file1.txt,采用字节流的话是这样读的:
				a中国bc张三fe
				第一次读:一个字节,正好读到'a'
				第二次读:一个字节,正好读到'中'字符的一半。
				第三次读:一个字节,正好读到'中'字符的另外一半。

		有的流是按照字符的方式读取数据的,一次读取一个字符,这种流是为了方便读取
		普通文本文件而存在的,这种流不能读取:图片、声音、视频等文件。只能读取纯
		文本文件,连word文件都无法读取。
			假设文件file1.txt,采用字符流的话是这样读的:
				a中国bc张三fe
				第一次读:'a'字符('a'字符在windows系统中占用1个字节。)
				第二次读:'中'字符('中'字符在windows系统中占用2个字节。)

综上所述:流的分类
	输入流、输出流
	字节流、字符流

java IO流这块有四大家族:

	四大家族的首领:
		java.io.InputStream  字节输入流
		java.io.OutputStream 字节输出流
        java.io.Reader		字符输入流
        java.io.Writer		字符输出流

	四大家族的首领都是抽象类。(abstract class)

	所有的流都实现了:
		java.io.Closeable接口,都是可关闭的,都有close()方法。
		流毕竟是一个管道,这个是内存和硬盘之间的通道,用完之后一定要关闭,
		不然会耗费(占用)很多资源。养成好习惯,用完流一定要关闭。

	所有的输出流都实现了:
		java.io.Flushable接口,都是可刷新的,都有flush()方法。
		养成一个好习惯,输出流在最终输出之后,一定要记得flush()
		刷新一下。这个刷新表示将通道/管道当中剩余未输出的数据
		强行输出完(清空管道!)刷新的作用就是清空管道。
		注意:如果没有flush()可能会导致丢失数据。


注意:在java中只要“类名”以Stream结尾的都是字节流。以“Reader/Writer”结尾的都是字符流。

java.io包下需要掌握的流有16个:

文件专属:
	java.io.FileInputStream(掌握)
	java.io.FileOutputStream(掌握)
	java.io.FileReader
	java.io.FileWriter

转换流:(将字节流转换成字符流)
	java.io.InputStreamReader
	java.io.OutputStreamWriter
	一个Reader可以和一个InputStream相结合。如果你有一个InputStream输入流,并且想从其中读取字符,可以把这个InputStream包装到InputStreamReader中。把InputStream传递到InputStreamReader的构造函数中:

缓冲流专属:
	java.io.BufferedReader
	java.io.BufferedWriter
	java.io.BufferedInputStream
	java.io.BufferedOutputStream

数据流专属:
	java.io.DataInputStream
	java.io.DataOutputStream

标准输出流:
	java.io.PrintWriter
	java.io.PrintStream(掌握)

对象专属流:
	java.io.ObjectInputStream(掌握)
	java.io.ObjectOutputStream(掌握)

重点:
	参与序列化的类型必须实现java.io.Serializable接口。
	并且建议将序列化版本号手动的写出来。
		private static final long serialVersionUID = 1L;

3、IO + Properties联合使用。
IO流:文件的读和写。
Properties:是一个Map集合,key和value都是String类型。

IO管道

Java IO中的管道为运行在同一个JVM中的两个线程提供了通信的能力。所以管道也可以作为数据源以及目标媒介。

你不能利用管道与不同的JVM中的线程通信(不同的进程)。在概念上,Java的管道不同于Unix/Linux系统中的管道。在Unix/Linux中,运行在不同地址空间的两个进程可以通过管道通信。在Java中,通信的双方应该是运行在同一进程中的不同线程。

//使用管道来完成两个线程间的数据点对点传递
    @Test
    public void test2() throws IOException {
        PipedInputStream pipedInputStream = new PipedInputStream();
        PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    pipedOutputStream.write("hello input".getBytes());
                    pipedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    byte []arr = new byte[128];
                    while (pipedInputStream.read(arr) != -1) {
                        System.out.println(Arrays.toString(arr));
                    }
                    pipedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

管道和线程 请记得,当使用两个相关联的管道流时,务必将它们分配给不同的线程。read()方法和write()方法调用时会导致流阻塞,这意味着如果你尝试在一个线程中同时进行读和写,可能会导致线程死锁。

管道的替代 除了管道之外,一个JVM中不同线程之间还有许多通信的方式。实际上,线程在大多数情况下会传递完整的对象信息而非原始的字节数据。但是,如果你需要在线程之间传递字节数据,Java IO的管道是一个不错的选择。

Java IO:网络

Java中网络的内容或多或少的超出了Java IO的范畴。关于Java网络更多的是在我的Java网络教程中探讨。但是既然网络是一个常见的数据来源以及数据流目的地,并且因为你使用Java IO的API通过网络连接进行通信,所以本文将简要的涉及网络应用。

当两个进程之间建立了网络连接之后,他们通信的方式如同操作文件一样:利用InputStream读取数据,利用OutputStream写入数据。换句话来说,Java网络API用来在不同进程之间建立网络连接,而Java IO则用来在建立了连接之后的进程之间交换数据。

基本上意味着如果你有一份能够对文件进行写入某些数据的代码,那么这些数据也可以很容易地写入到网络连接中去。你所需要做的仅仅只是在代码中利用OutputStream替代FileOutputStream进行数据的写入。因为FileOutputStream是OuputStream的子类,所以这么做并没有什么问题。

System.in, System.out, System.err

JavaIO流面试题

什么是IO流?

它是一种数据的流从源头流到目的地。比如文件拷贝,输入流和输出流都包括了。输入流从文件中读取数据存储到进程(process)中,输出流从进程中读取数据然后写入到目标文件。

字节流和字符流的区别。

字节流在JDK1.0中就被引进了,用于操作包含ASCII字符的文件。JAVA也支持其他的字符如Unicode,为了读取包含Unicode字符的文件,JAVA语言设计者在JDK1.1中引入了字符流。ASCII作为Unicode的子集,对于英语字符的文件,可以可以使用字节流也可以使用字符流。

Java中流类的超类主要由那些?

java.io.InputStream java.io.OutputStream java.io.Reader java.io.Writer

FileInputStream和FileOutputStream是什么?

这是在拷贝文件操作的时候,经常用到的两个类。在处理小文件的时候,它们性能表现还不错,在大文件的时候,最好使用BufferedInputStream (或 BufferedReader) 和 BufferedOutputStream (或 BufferedWriter)

System.out.println()是什么?

println是PrintStream的一个方法。out是一个静态PrintStream类型的成员变量,System是一个java.lang包中的类,用于和底层的操作系统进行交互。

什么是Filter流?

Filter Stream是一种IO流主要作用是用来对存在的流增加一些额外的功能,像给目标文件增加源文件中不存在的行数,或者增加拷贝的性能。

有哪些可用的Filter流?

在java.io包中主要由4个可用的filter Stream。两个字节filter stream,两个字符filter stream. 分别是FilterInputStream, FilterOutputStream, FilterReader and FilterWriter.这些类是抽象类,不能被实例化的。

在文件拷贝的时候,那一种流可用提升更多的性能?

在字节流的时候,使用BufferedInputStream和BufferedOutputStream。 在字符流的时候,使用BufferedReader 和 BufferedWriter

说说管道流(Piped Stream)

有四种管道流, PipedInputStream, PipedOutputStream, PipedReader 和 PipedWriter.在多个线程或进程中传递数据的时候管道流非常有用。

说说File类

它不属于 IO流,也不是用于文件操作的,它主要用于知道一个文件的属性,读写权限,大小等信息。

说说RandomAccessFile?

它在java.io包中是一个特殊的类,既不是输入流也不是输出流,它两者都可以做到。他是Object的直接子类。通常来说,一个流只有一个功能,要么读,要么写。但是RandomAccessFile既可以读文件,也可以写文件。 DataInputStream 和 DataOutStream有的方法,在RandomAccessFile中都存在。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值