蒟蒻的Java入门之旅——IO流基础

一、IO流的分类

1.从流动类型上分类,Java的IO流分为输入流和输出流两类。
对于输入输出流应根据当前操作进行区分。

输入流:大多数情况下输入流对接的是非内存区域(也有内存流向内存的转移),目的是将数据读入所需内存区中进行处理,以内存区为终点。

输出流:和输入流恰恰相反,大多数情况下输出流的职能主要是将内存中的储存的数据输出至非内存区域,以内存区为起点。

2.从读取类型上分类,主要分为字节流和字符流。

字节流:以InputStream和OutputStream作为主类,处理单位为字节,由于图像和音视频文件在储存时以字节的形式,因此字节流对这些文件的操作更为便利。

字符流:在Java中采用Unicode编码机制,也可利用InputStreamReader和OutputstreamWriter进行字节流向字符流的解码转换,大多数情况下对文字的操作利用字符流更为便利。

3.从流发生的源头来看,可以分为节点流和过滤流。

节点流:用于直接对目标设备进行操作的流。例如文件流、字节数组流、标准输入输出流,对接构造函数往往是数据空间,文件、字节数组等等。

过滤流:可以为程序提供按照封装的指定行为操作节点流的功能,以更加灵活方便的方式读写多种类型的数据,构造方法参数往往是其他流。

二、字节流子类及使用场合
字节流子类:
ByteArrayInputStream:

在类的实例化时便需要一个字节数组作为流的源头,用于对字节的读取,并且能将在源头中的数据通过read方法,将流中的数据读取至缓冲区数组,也可利用功能进行标记,选择性读取数据。

举例:

package none;
import java.io.*;
public class Test{
	public static void main(String[] args) {
		byte[] a = {0x10,0x11,0x22,0x33,0x44,0x55,0x66};
		ByteArrayInputStream in = new ByteArrayInputStream(a);
        int buf = in.read();
        System.out.print(buf);
        }
}

输出结果为16,buf中的数据是从流a中读取的。

对应的字符流:
CharArrayReader

字节流子类:

FileInputStream
用于读取诸如图像数据之类的原始字节流,也能从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。

举例:

package none;
import java.io.*;
public class Test{
	public static void main(String[] args) throws IOException {
	FileInputStream a=new FileInputStream(new File("a.text"));
	byte[] b=new byte[a.available()];
	a.read(b);
	a.close();
	String str2=new String(b);
	System.out.println(str2);
        }
}

输出为文件a中的内容,利用字符串的构造方法,将字节数组解码构造为字符串。

对应字符流:
FileReader

字节流子类:
FilterInputStream

FilterInputStream 包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。FilterInputStream 类本身只是简单地重写那些将所有请求传递给所包含输入流的 InputStream 的所有方法。FilterInputStream 的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。

用法:封装了三大功能性子类,对节点流进行封装,实现基本功能与特殊操作。

字节流子类:

BufferedInputStream

“BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。”

使用举例:

package none;
import java.io.*;
public class Test{
	public static void main(String[] args) throws IOException {
	FileInputStream a=new FileInputStream(new File("a.text"));
	BufferedInputStream in =new BufferedInputStream(a);
	byte[] b=new byte[a.available()];
	in.read(b);
	String c=new String(b);
	System.out.println(c);
	a.close();
	in.close();
        }
}

对应字符流:

BufferedReader

字节流子类:
DataInputStream

封装了多种读取方法实现对数据的读取,允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型。其读取方法都是根据数据类型的字节数来读取基本数字类型(注意只能以字节形式读取),由于Java的各数据类型字节是固定不变的,所以该读取流使用于多种系统。

字节流子类:
ObjectInputStream
字节流子类:
PipedInputStream
输出流与输入流语句对称,用法相似,输出流如下:

注意输入流中是从流中读取数据,输出流是将数据输出至流中。

ByteArrayOutputStream
FileOutputStream
FilterOutputStream
BufferedOutputStream
ObjectOutputStream
PipedOutputStream
特别的其中特别的有

字节流子类:
PrintStream
PrintStream 在输出时能自动完成两项功能:如果输出字符串,则完成字符的编码过程,如果有汉字,则将汉字转变成操作系统本身的字符集。另外,如果其输出路径上有缓冲流,当调用println和输出字符串换行时,自动调用缓冲流的flush,在其构造方法中可设定是否开启自动刷新功能,默认为false。

对应的字符流子类:

PrintWriter

使用样例:

package none;
import java.io.*;
public class Test{
	public static void main(String[] args) throws IOException {
			PrintWriter to=new PrintWriter(new OutputStreamWriter(System.out),true);
			to.println("hello");//换行形式输出才能输出数据
	}
}

三、字节流与字符流的转换

文件在硬盘中的储存形式是以字节计数的,而当从文件中读取数据时,往往需要以字符的形式显示。因此,无论是单一使用字符流还是字节流都无法完成读取需求,因此涉及到流的转换。Java中固定的基本数据大小为编码解码提供了便利。并且字节流向字符流的转换是以流的装配为实现形式的。通常使用InputStreamReader与OutputStreamWriter类实现。这两个类中的构造函数可以分别接受多种类型的字节输入与输出流的对象引用作为参数。

四、过滤流

过滤流的两大抽象父类:

FilterInputStream
FilterOutputStream

他们分别重写了InputStream和OutputStream的所有方法,使得他们既能实现基输入输出流流的操作,又能进行数据的特殊操作。使用过滤流时通常需要将过滤流绑定到节点流上,在构造方法中指定要绑定的节点流。

举例(读取文件):

package none;
import java.io.*;
public class Test{
	public static void main(String[] args) throws IOException {
		InputStreamReader in=new InputStreamReader(new FileInputStream("a.text"));
		char[] b=new char[10]; 
		in.read(b);
		System.out.println(b);
	}
}

此处输出的是文件中的字符,如果不使用InputStreamReader,则会输出文件中的字节。将字节读取文件流绑字节字符转换流上。

五、对象的序列化与反序列化
对象的序列化:把动态对象转换为可以传输的字节序列。

对象的反序列化:把字节序列恢复为动态对象。

**相关介绍:**对象的序列化的目的是为例便于网络传输和介质储存,网络传输中序列化往往与编列相关。例如,在分布式通信中,常常需要不同设备之间发送调用请求,请求包括调用的方法参数等信息,这些参数在传送前必须进行编列,在接收后也必须进行反编列。因此,必须进行序列化后才能编列,只有反编列后才能反序列化。

Java中的实现支持:
Java中提供了Serializable接口,只有实现了这个接口的类才能被序列化与反序列化。但是,当一个对象声明了Seriliazable接口时只是表示该类加入对象串行化协议。
类ObjectOutputStream和ObjectInputStream分别实现了接口ObjectOutput和ObjectInput,调用writeObject方法用于将对象输出至流中,例如将OutputStream绑定文件流后将对象写入文件中持久化储存,这为分布式技术提供了支撑。同样的,后者的readObject方法可以对对象进行读取,绑定文件流后可从文件流中读取对象。

六、Java中的File类及其支持
1.File类
表示:因为目录是特殊的文件,所以File类是文件与目录的总称。
作用:将文件封装为类并通过提供储存路径构造为对象,便于程序在内存中对文件进行读写等各类操作。

2.Java对文件读写的支持
Java中目前提供了能分别从字节和字符角度对文件进行处理的类。

2.1 单向操作(只能读或写)
字节:
FileInputStream
FileOutputStream

字符:
FileReader
FileWriter

2.2 双向操作(支持读写)

随机文件操作RandomAccessFile:
构造方法:
RandomAccessFile(File file,String mode)
RandomAccessFile(String name,String name)

mode类型:

r : 只读
rw : 读写
rws : 同步读写(包含文件内容和属性)
rwd : 同步读写(不包含文件内容和属性)

2.3 文件过滤接口
在类中实现接口FilenameFilter,文件过滤接口可用于列出所有满足过滤条件的文件名清单。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值