您的位置:首页 > 编程语言 > Java开发

你必须知道的261个Java语言问题笔记- Java流和文件操作2

2017-08-10 00:01 495 查看
何如实现字节流和字符流之间的转化

Excel、Word和PDF等文件不属于纯文本文件,因为文件中除了包含字符信息外还有很多格式信息,

因此如果使用字符流读写这类文件会出现乱码问题。对这类文件的读写操作需要使用第三方组件,

对Word文件的操作可以使用Jacob、iText、POI和java2word,对Excel文件的操作可以使用POI和

JXL,而PDF文件的操作可以使用iText、pdfbox、xpdf.

InputStreamReader:

是字节流通向字符流的桥梁,可完成字节流到字符流的转化。它使用指定字符集读取字节并将其

解码为字符,使用的字符集可以显示给定,否则可能接受平台默认的字符集。中文操作系统的

默认编码为GBK.

为了达到最高效率,可以考虑使用BufferedReader包装InputStreamReader.

OutputStreamWriter:

是字符流通向字节流的桥梁,可完成字符流到字节流的转化。它使用指定的字符集将向其写入的

字符编码为字节。它使用的字节集可以显示给定,否则可能接受平台默认的字符集。

为了达到最高效率,可以考虑使用BufferedWriter包装OutputStreamWriter来避免频繁调用转换器。

如何判断要读的文件是否到达末尾

在读文件操作时,主要使用InputStream字节输入流和Reader字符输入流,判断文件是否到达末尾的

方法如下:

InputStream字节输入流的read()方法返回读取的字节信息,如果到达流的末尾,则返回-1.

InputStream字节输入流的read(byte[]b)方法返回读取到byte[]数组中的总字节数,如果已到达末尾

而不再有数据,则返回-1.

Reader字符输入流的read()方法返回读取的字节信息,如果到达流的末尾,则返回-1.

Reader字符输入流的read(char[] cbuf)方法返回读取到char[]数组中的总字符数,如果已到达流

末尾而不再有数据,则返回-1.

BufferedInputStream类的readLine()方法读取的一行内容的字符串,不包含换行符和回车符,如果

已到达流末尾。则返回null.

如何读文件、写文件?

读文件

读文件时可根据文件类型的不同采用不同的读取方式。

如果是原始字节流文件:

public void testBufferedInputStream() throws Exception{
int tmp = -1;
FileInputStream fs = new FileInputStream("D:\\测试.txt");
BufferedInputStream bs = new BufferedInputStream(fs);
while((tem=bs.read())!=-1){
System.out.print((char)tmp);
}
bs.close();
fs.close();

}

如果是纯文本字符文件:

public void testBufferedReader() throws Exception{
FileReader f = new FileReader("D:\\测试.txt");
BufferedReader br = new BufferedReader(f);
String tmp = null;
while((tmp=br.readLine())!=null){
System.out.println(tmp);
}
br.close();
f.close();

}

写文件:

写文件时可根据文件类型的不同采用不同的写入方式。

在写入时,如果目标文件不存在,首先会尝试自动创建文件,然后再执行写入操作。

如果目标文件的父目录不正确,文件自动创建将失败。

public void testPrintStream() throws Exception{
FileOutStream f = new FileOutputStream("D:/outtest.txt");
BufferedOutputStream b = new BufferedOutStream(f);
b.write('A');
b.write('B');
ps.close();
f.close();

}

如果是纯文本字符文件:

public void testPrintWriter() throws Exception{
FileWriter fw = new FileWriter("D:/writertest.txt");
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter pw = new Printwriter(bw);
pw.println("从helloworld开始");
pw.close();
pw.close();
bw.close();
fw.close();

}

如何以追加的方式写文件

FileOutputStream和FileWriter类的构造方法都提供了一个参数,该参数可控制是否采取追加写入

的方式写文件。一般写文件时,默认采取覆盖方式,即文件中只保留最近一次写的内容,如果需要

采取追加写入的方式,只要修改上述两个类的构造参数即可。

如何实现文件和文件夹的复制

文件复制;

文件夹复制;

如何在文件的任意位置进行读写

RandomAccessFile类是一种特殊的文件流,它同时实现了DataInput和DataOutput接口,因此

可以用它来读写文件。RandomAccessFile通过一个文件指针来指定读写的位置,默认该指针处于

文件开始处。该文件指针可以通过getFilePointer()方法读取,并通过seek()方法设置。

可通过seek()方法控制指针位置,实现在文件的任何位置读取或者写入数据。

RandomAccessFile类提供了两个构造方法:

public RandomAccessFile(File file,String mode) throws FileNotFoundException;

public RandomAccessFile(String name,String mode) throws FileNotFoundException;

第一个参数用于指定目标文件,第二个参数mode用于指定操作模式。

RandomAccessFile可使用的操作模式;

r:以只读方式打开。调用结果对象的如何write方法都将导致抛出IOException;

rw:打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件;

rws:打开以便读取和写入,对于rw,还要求对文件的内容或元数据的每个更新都同步写入到基础设备

rwd:打开以便读取和写入,对于rw,还要求对文件内容的每个更新都同步写入到基础存储设备。

使用Buffered缓冲流写文件,为什么内容没有写入

在OutputStream和Writer输出流中,都提供flush()和close()两个方法。

flush()方法用于刷新输出流并强制写出所有缓冲的输出的字节。

close()方法用于关闭输出流并释放与此流有关的所有系统资源。

在使用缓冲流写文件时,是将信息先写入缓冲区,如果不显示调用flush()和close()方法,

则无法将缓冲区中的信息输出到目标文件中,因此文件为空。

如何实现文件的分割和合并

使用RandomAccessFile类可实现文件的分割和合并功能,该类具有在文件任意位置进行读写功能。

例如多线程下载、断点续传等动能都需要用到文件分割和合并功能。

什么是NIO?与I/O有什么区别和联系

原有的I/O操作都是以字节为单位进行读写的,虽然应用时使用了很多高级流进行了封装,不需要

直接去处理字节流,但是底层的实现还是离不开字节处理。原有的I/O操作是一次一个字节的处理

数据,速度比较慢;此外InputStream中的read()是一种阻塞性的方法,该方法可用于从流中读取

数据,但是如果数据源没有数据,它将一直等待,其他程序也不能执行。

为了解决原有I/O的一些问题,从JDK1.4开始提供了一系列改进I/O处理的新特性,这些改进功能

和特性被称为"新I/0"(NEW I/0,简称NIO))。NIO新增了很多处理I/O的类,这些类都放在java.nio

及其子包中,并且对原有java.io包中的很多类进行了改进,新增了满足NIO的功能。

NIO与原有I/O有同样的作用和目的,是基于原有I/O的改进和扩展。NIO与原有I/O不同,它是基于

特殊缓冲区块(Buffer)进行的高效的I/O操作。NIO的缓冲块与普通的缓冲区不同,它是一块连续的

空间,它内存的分配不在Java的堆栈中,不受Java内存回收的影响;它的实现不是纯Java的代码,

而是本地代码,这样操作系统可以直接与缓冲区进行交互,Java程序只需要完成对缓冲区的读写,

而后续操作由操作系统完成。

异步通道Channel是NIO的另外一个重要的新特点。Channel并不是对原有I/0类的扩充和完善,而是

完全崭新的实现。通过Channel,Java应用程序能够更好的与操作熊I/O服务结合起来,充分地利用

Buffer缓冲区,完成高性能的I/O操作,Channel的实现也不是纯Java的,而是和操作系统结合紧密

的本地代码。

NIO与原有I/O相比,NIO新特性主要体现在以下几个方面:

更加灵活的可伸缩的I/O接口,包括I/O抽象Channels的出现以及新的多元的,非阻塞的I/O机制。

这使得构建产品级的应用服务更加方便灵活,使用户能够轻松应付成千上万个开放的连接,并且

可以有效地利用多个处理器。

快速缓存的二进制和字符I/O接口。快速缓存的二进制I/O的API使得用户可以很容易地编写出操作

文件流或者二进制数据流的高性能代码。而快速缓存的字符I/O的API使得用户可以更加高效地处理

字符流和文件,此处它还将正则表达式引入到Java平台中来格式化用户的输入和输出。

字符集的编码器和解码器。这些字符集转换API使得用户可以直接访问操作系统内置的字符集转换

器,同时还支持那些外来的转换器。

基于Perl风格正则表达式的模式匹配机制。

改良的文件系统接口,支持锁定和内存映射。该特性使得用户可以更加容易地处理各种文件系统操作

中出现的问题,同时使得用户可以更加高效地访问大量的文件属性集。此外如果用户确实需要,还

可以访问与平台相关一些特性。最后,它还提供对非本地文件系统的支持。

新的I/O违例类可以使用户更加有针对性地来处理各种I/O错误,让用户能够在各种平台上一致地来对

待这些错误。

增加了对并发的支持,NIO类中的大部分方法都支持多个并发的线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: