java io流过滤流_JAVA io流 文件流 字节流 字符流 过滤流 缓冲流

一、概念

1.1、按流向分类:

输入流: 程序可以从中读取数据的流。

输出流: 程序能向其中写入数据的流。

1.2、按数据传输单位分类:

字节流:以字节(8位二进制)为单位进行处理。主要用于读写诸如图像或声音的二进制数据。

字符流:以字符(16位二进制)为单位进行处理。都是通过字节流的方式实现的。字符流是对字节流进行了封装,方便操作。在最底层,所有的输入输出都是字节形式的。

字节流和字符流的区别:

读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

1.3、按功能分类:

节点流:从特定的地方读写的流类,如磁盘或者一块内存区域。

过滤流:使用节点流作为输入或输出。过滤流是使用一个已经存在的输入流或者输出流连接创建的。

java IO流处理主要包括以下几个部分:

二、File类

2.1、描述

File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。

2.2、路径名

在处理 UNIX 平台的根目录,以及 Microsoft Windows 平台的盘符、根目录和 UNC 路径名时,将用到前缀这一概念。如下所示:

对于 UNIX 平台,绝对路径名的前缀始终是"/"。相对路径名没有前缀。表示根目录的绝对路径名的前缀为 "/" 且名称序列为空。

对于 Microsoft Windows 平台,包含盘符的路径名前缀由驱动器号和一个 ":" 组成。如果路径名是绝对路径名,还可能后跟"\\"。UNC 路径名的前缀是"\\\\";主机名和共享名是名称序列中的前两个名称。没有指定驱动器的相对路径名没有前缀。 (D:\\Java)

一般推荐都写成”/”使得在UNIX和Windows下通用。或者使用File类的一个静态变量:

2.3、文件管理:

创建文件:

当创建完File对象时,通过调用其createNewFile()方法在相应的目录下创建文件(此方法创建的不是文件夹)

booleancreateNewFile()

当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。

2.4、目录管理:

创建目录:

boolean mkdir()

创建此抽象路径名指定的目录。

列出目录中的文件和目录

String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。

File[] listFiles()返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。

判断是文件还是目录:

boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。

boolean isFile()测试此抽象路径名表示的文件是否是一个标准文件。

判断文件或目录是否存在:

boolean exists()测试此抽象路径名表示的文件或目录是否存在。

删除文件或目录:booleandelete()删除此抽象路径名表示的文件或目录。

返回文件或目录的名称:String  getName()返回由此抽象路径名表示的文件或目录的名称。

将路径转换为字符串:String  getPath()将此抽象路径名转换为一个路径名字符串。

判断路径或文件是否可读和可写:boolean canRead()测试应用程序是否可以读取此抽象路径名表示的文件。

booleancanWrite()测试应用程序是否可以修改此抽象路径名表示的文件。

2.5、创建File并在硬盘上生成文件:

调用File(String pathname)构造方法:

public static void main(String[] args) {

File file = new File("D:/filetest");

try {

file.createNewFile();

} catch (IOExceptione) {

e.printStackTrace();

}

}

调用File(File parent, String child)构造方法:

File file = new File("D:/itzhai");

if(!file.exists()){

file.mkdir();

}

File file2 = new File(file, "arthinking.txt");

file2.createNewFile();

2.6、使用FilenameFilter过滤文件:

java.io接口FilenameFilter

public interface FilenameFilter

实现此接口的类实例可用于过滤器文件名。Abstract Window Toolkit 的文件对话框组件使用这些实例过滤File 类的 list 方法中的目录清单。

FilenameFilter里面只定义了一个方法,该方法被文件列表中的每个文件调用一次:

boolean accept(File dir,String name)测试指定文件是否应该包含在某一文件列表中。

参数:dir - 被找到的文件所在的目录。name - 文件的名称。

返回:当且仅当该名称应该包含在文件列表中时返回 true;否则返回 false。

通过调用File的以下方法过滤:

String[] list(FilenameFilter filter)返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。

File file = new File("D:/itzhai");

String [] filenames = file.list(new FilenameFilter(){

@Override

public booleanaccept(File dir, String name) {

if(name.endsWith(".txt")){

return true;

}

return false;

}

});

for(String filename : filenames){

System.out.println(filename);

}

三、RandomAccessFile类

该对象并不是流体系中的一员,其封装了字节流,同时还封装了一个缓冲区(字符数组),通过内部的指针来操作字符数组中的数据。 该对象特点:

该对象只能操作文件,所以构造函数接收两种类型的参数:a.字符串文件路径;b.File对象。

该对象既可以对文件进行读操作,也能进行写操作,在进行对象实例化时可指定操作模式(r,rw)

四、字节流

字节流是执行基于8位字节的输入和输出,它一次读写一字节的数据。字节流是I / O的最底层流技术,因此,如果你正在阅读或写入字符数据的最佳方法是使用字符流。其他流类型是建立在字节流之上的(如Java中的InputStream、OutputStream)。

4.1、输入流:

4.1.1、字节输入流抽象类及其关键的方法:

java.io类InputStreamjava.lang.Object

java.io.InputStream

abstractint read()从输入流中读取数据的下一个字节。intread(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组b中。intread(byte[] b, int off, int len)将输入流中最多len个数据字节读入byte数组。

4.1.2、输入流的操作:

打开一个输入流,循环读取,关闭输入流

这里使用InputStream的子类FileInputStream读入文件:

publicstaticvoidmain(String[] args)throwsIOException {

//创建文件输入流

InputStream is =newFileInputStream("D:/itzhai/arthinking.txt");

//创建字节缓冲

byte[] buffer =newbyte[100];

intlength = 0;

//以字节形式循环读取文件

while((length = is.read(buffer, 0, buffer.length)) != -1){

//把字节转换成字符并输出

String str =newString(buffer, 0, length);

System.out.println(str);

}

}

4.1.3、抽象类InputStream的类层次:

4.1.4、字节数组输入流ByteArrayInputStream

把字节数组作为源的输入流。

相关例子:

字节数组输入流:

publicstaticvoidmain(String[] args) {

//创建读取数据源

String input ="arthinking";

//获取字节数组

byte[] b = input.getBytes();

//创建字节数组输出流

ByteArrayInputStreambis =newByteArrayInputStream(b);

//循环逐个读取

for(inti = 0; i < input.length(); i++){

intc;

//读取下一个字节

while((c = bis.read()) != -1){

System.out.print((char)c);

}

}

//将缓冲区的位置重置为标记位置

bis.reset();

}

字节数组输出流:

publicstaticvoidmain(String[] args)throwsIOException {

//创建字节输出流

ByteArrayOutputStreambos =newByteArrayOutputStream();

String output ="arthinking";

//创建需要输出的字节数组

byte[] buffer = output.getBytes();

//把字节数组写到输出流

bos.write(buffer);

//创建文件输出流

OutputStream os =newFileOutputStream("D:/itzhai/arthinking.txt");

//把字节输出流写到文件输出流

bos.writeTo(os);

}

4.2、输出流:

4.2.1、字节输出流的抽象类及其最关键的方法:

java.io类OutputStreamjava.lang.Object java.io.OutputStream

void write(byte[] b)将b.length个字节从指定的byte数组写入此输出流。voidwrite(byte[] b, int off, int len)将指定byte数组中从偏移量off开始的len个字节写入此输出流。abstractvoid write(int b)将指定的字节写入此输出流。

由此可以看出,只有最后一个方法才是抽象的,原因是前面两个都调用了第三个抽象方法,这样继承这个抽象类的子类都必须提供抽象的write(int b)的实现,从而使得每个子类的实现都不一样。

4.2.2、输出流的操作:

打开输出流循环写入关闭输入流

这里使用了OutputStream的子类FileOutputStream输出到文件:

publicstaticvoidmain(String[] args)throwsIOException {

//创建一个输出流

OutputStream os =newFileOutputStream("D:/itzhai/arthinking.txt", true);

String output ="http://www.itzhai.com";

//从字符串中获取字节数组

byte[] buffer = output.getBytes();

//写出到输出流

os.write(buffer);

//关闭输出流

os.close();

}

4.2.3、抽象类OutputStream的类层次结构:

五、过滤流:

“连接”在已存在的流(节点流或处理流)之上通过对数据的处理为程序提供更为强大的读写功能。过滤流是使用一个已经存在的输入流或输出流连接创建的,过滤流就是对节点流进行一系列的包装。例如BufferedInputStream和BufferedOutputStream,使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率,以及DataInputStream和DataOutputStream,使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。他们都属于过滤流。

过滤流不能直接跟文件打交道,只能通过节点流进行相关的操作。可以从其构造方法中看出:

FilterOutputStream(OutputStream out)需要传入一个OutputStream。

在InputStream和OutputStream的子类中,FilterInputStream和FilterOutputStream是过滤流,其又派生出子类DataInputStream和DataOutputStream数据输入流和数据输出流。

过滤流的主要特点是在输入输出数据同时对所传输的数据做指定类型或格式的转换。

3.1、缓冲输出流BufferedOutputStream

该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。

当缓冲区写满或者关闭输出流时,一次性输出到流,或者调用flush()方法主动将缓冲区输出到流。

3.2、过滤流的使用例子:

使用过滤流类BufferedOutputStream和DataOutputStream装饰FilterOutputStream的例子:

publicstaticvoidmain(String[] args)throwsIOException {

//创建数据输出流

DataOutputStream dos=newDataOutputStream(

newBufferedOutputStream(newFileOutputStream("D:/itzhai/arthinking.txt")));

bytea = 1;

charb ='a';

intc = 2;

//使用数据输出流对象的方法写出数据到输出流

dos.write(a);

dos.write(b);

dos.write(c);

//关闭数据输出流

dos.close();

//创建数据输入流

DataInputStream dis =newDataInputStream(

newBufferedInputStream(newFileInputStream("D:/itzhai/arthinking.txt")));

//使用数据输入流的方法从输入流中读取数据

System.out.println(dis.readByte() + dis.readChar() + dis.readInt());

//关闭数据输入流

dis.close();

}

使用DataInputStream和DataOutputStream数据文件流的一般步骤:

①创建字节文件流对象②基于字节文件流对象建立数据文件流对象③用数据文件流对象的方法对基本类型的数据进行输入/输出

4、IO流的链接:

Input Stream Chain

FileInputStream --> BufferedInputStream --> DataInputStream-->数据

Output Stream Chain

数据--> DataOutputStream --> BufferedOutputStream -->FileOutputStream

六、字符流(Chcaracter Streams):

字符流是执行基于16位字节(即两字节)的输入和输出,它一次读写一个字符(两个字节)的数据。所有的字符流类都是从Reader、Writer两个类延伸下来的,我们可以使用FileReader、FileWriter类进行读写I/O文件

6.1、BufferedReader

BufferedReader能为字符输入流提供缓冲区,可以提高许多IO处理的速度。你可以一次读取一大块的数据,而不需要每次从网络或者磁盘中一次读取一个字节。特别是在访问大量磁盘数据时,缓冲通常会让IO快上许多。

BufferedReader和BufferedInputStream的主要区别在于,BufferedReader操作字符,而BufferedInputStream操作原始字节。只需要把Reader包装到BufferedReader中,就可以为Reader添加缓冲区(译者注:默认缓冲区大小为8192字节,即8KB)。代码如下:

Readerinput = newBufferedReader(newFileReader("c:\\data\\input-file.txt"));

这个例子设置了8KB的缓冲区。最好把缓冲区大小设置成1024字节的整数倍,这样能更高效地利用内置缓冲区的磁盘。

除了能够为输入流提供缓冲区以外,其余方面BufferedReader基本与Reader类似。BufferedReader还有一个额外readLine()方法,可以方便地一次性读取一整行字符。

6.2、BufferedWriter

与BufferedReader类似,BufferedWriter可以为输出流提供缓冲区。可以构造一个使用默认大小缓冲区的BufferedWriter(译者注:默认缓冲区大小8 * 1024B),代码如下:

Writerwriter = newBufferedWriter(newFileWriter("c:\\data\\output-file.txt"));

也可以手动设置缓冲区大小,代码如下:

Writerwriter = newBufferedWriter(newFileWriter("c:\\data\\output-file.txt"),8* 1024);

为了更好地使用内置缓冲区的磁盘,同样建议把缓冲区大小设置成1024的整数倍。除了能够为输出流提供缓冲区以外,其余方面BufferedWriter基本与Writer类似。类似地,BufferedWriter也提供了writeLine()方法,能够把一行字符写入到底层的字符输出流中。值得注意是,你需要手动flush()方法确保写入到此输出流的数据真正写入到磁盘或者网络中。

6.3、FilterReader

与FilterInputStream类似,FilterReader是实现自定义过滤输入字符流的基类,基本上它仅仅只是简单覆盖了Reader中的所有方法。

就我自己而言,我没发现这个类明显的用途。除了构造函数取一个Reader变量作为参数之外,我没看到FilterReader任何对Reader新增或者修改的地方。如果你选择继承FilterReader实现自定义的类,同样也可以直接继承自Reader从而避免额外的类层级结构。

6.4、FilterWriter

内容同FilterReader,不再赘述。

七、字符流与字节流转换

7.1转换流的特点:

其是字符流和字节流之间的桥梁

可对读取到的字节数据经过指定编码转换成字符

可对读取到的字符数据经过指定编码转换成字节

7.2何时使用转换流?

当字节和字符之间有转换动作时;

流操作的数据需要编码或解码时。

7.3具体的对象体现:

InputStreamReader:字节到字符的桥梁

OutputStreamWriter:字符到字节的桥梁

这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值