学习记录(探究java i/o)

输入/输出:探究java.io
本章将介绍打包在java.io中的基于流的I/O系统,它们自Java最初发布以来就已提供且被广泛使
用从1.4版本开始,java添加量另一套I/O系统,被称为NIO(也就是新I/O)NIO被打包到java.nio
及其子包中。

1 I/O类和接口
(见截图)

2 File 类
尽管java.io定义的大多数类用于操作流,但File不是。File类直接处理文件和文件系统。
也就是说,File类没有指定如何从文件检索信息以及如何向文中存储信息,而是描述了文件
本身的属性。
File对象用于获取和操作与磁盘文件相关的信息,例如权限、时间、日期以及目录路径,并且还可以浏览子目录层次。
注意:Path接口和Files类是NIO系统的一部分,在许多情况下都为File类提供了强大的替换方案。

File的构造函数(4种)
注意:在Windows版本的java中使用正斜杠(/),那么路径仍然会被正确解析。
如果使用windows约定的反斜杠(\),那么在字符串中需要使用转义字符序列(\\)。
Java使用介于unix和windows约定之间的路径分隔符。

File类中定义了获取File对象中标准属性的方法。例如:
getName()方法返回文件的名称;
getParent()方法返回父目录名;
如果文件存在,exists()返回true,否则返回false。

2.1 目录
String[] list();

2.2 使用FilenameFilter接口
使返回结果只包含匹配特定文件名模式的那些文件。可以使用list()的第二种形式:
String[] list(FilenameFilter FFObj)
其中FFObj是实现了FilenameFilter接口的类的对象。
FilenameFilter接口只定义了方法accept(),该方法针对列表中的每个文件调用一次,一般形式
如下:
boolean accept(File directory,String filename)

2.3 listFiles()方法
File[] listFiles()
File[] listFiles(FilenameFilter FFObj)
File[] listFiles(FileFilter FObj)

3 AutoCloseable、Closeable和Flushable接口
..AutoColseable接口只定义了close()方法:
void close() throws Exception
..Closeable接口也定义了close()方法。实现了Closeable接口的类的对象可以被关闭。
从JDK7开始,Closeable扩展了AutoCloseable。因此,所有实现了Closeable接口的类
也都实现了AutoCloseable接口。
..实现了Flushable接口的类的对象,可以强制将缓冲的输出写入与对象关联的流中。
该接口定义了flush()方法,如下:
void flush() throws IOException
刷新流通常会导致缓冲的输出被物理地写入底层设备中。写入流的所有I/O类都实现了
Flushable接口。

4 I/O异常
如果发生I/O错误,就会抛出IOException异常。
如果文件无法打开,会抛出FileNotFoundException异常。
FileNotFoundException异常是IOException的子类。

5 关闭流的两种方式
第一种是显式地在流上调用close()方法
第二种是使用jdk7新添加的带资源的try语句,从而自动执行这一过程。
..关于带资源的try语句的3个关键点:
1.由带资源的try语句管理的资源必须是实现了AutoCloseable接口的类的对象。
2.在try代码中声明的资源被隐式声明为final。
3.通过使用分号分隔每个声明可以管理多个资源。
出自之外:所声明的资源的作用域被限制在带资源的try语句中。

6 流类
当操作字符或字符串时,应当使用字符流;当操作字节或其他二进制对象时,使用字节流。

7 字节流
字节流为处理面向字节的I/O提供了丰富的环境。字节流可以用于任意类型的对象,包括二进制
数据。
InputStream和OutputStream位于字节路的顶层。

7.1 InputStream类
InputStream是抽象类,定义了Java的流字节输入模型,并且还实现了AutoCloseable和
Closeable接口。当发生I/O错误时,该类中的大部分方法都会抛出IOExeption异常(mark()和
markSupported()除外)。

7.2 OutputStream类
OutputStream是定义流字节输出的抽象类,实现了AutoCloseable、Closeable以及Flushable
接口。该类中的大部分方法都返回void,并且如果发生I/O错误,大部分方法会抛出
IOException异常。

7.3 FileInputStream类
使用FileInputStream类创建的InputStream对象可以用于从文件读取字节。两个常用的构造函
数如下所示:
FileInputStream(String filePath)
FileInputStream(File fileObj)
这两个构造函数都会抛出FileNotFoundException异常。其中,filePath是文件的完整路径名,
fileObj是描述文件的File对象。

7.4 FileOutputStream类
FileOutputStream类创建能够用于向文件中写入字节的OutputStream对象。
该类实现了AutoCloseable、Closeable以及Flushable接口。

7.5 ByteArrayInputStream类
ByteArrayInputStream是使用字节数组作为源的输入流的一个实现。
两个构造函数:
ByteArrayInputStream(byte[] array)
ByteArrayInputStream(byte[] array,int start,int numBytes)

7.6 ByteArrayOutputStream类
ByteArrayOutputStream是使用字节数组作为目标的输出流的一个实现。
构造函数:
ByteArrayOutputStream()
ByteArrayOutputStream(int numBytes)
在第一种形式中,创建一个32字节的缓冲区。
在第二种形式中,创建一个由numBytes指定大小的缓冲区。
缓冲区被保存在ByteArrayOutputStream中受保护的buf域变量中。
如果需要的话,缓冲区的大小会自动增加。
缓冲区能够保存的字节数量包含在ByteArrayOutputStream中受保护的count域变量中。
close()方法对ByteArrayOutputStream对象没有效果。所以,不需要为ByteArrayOutputStream
对象调用close()方法。如果调用的话也不会产生错误。

7.7 过滤的字节流
过滤的字节流是简单的封装器,用于封装底层的输入流或输出流,并且还透明地提供一些扩展
级别地功能。这些流一般是通过接收通用流地方法访问地,通用流是过滤流地超类。
典型的扩展是缓冲、字符转换以及原始数据转换。过滤的字节流类是FilterInputStream和
FilterOutputStream,他们的构造函数如下所示:
FilterOutputStream(OutputStream os)
FilterInputStream(InputStream is)
这两个类提供的方法与InputStream和OutputStream类中的方法相同。

7.8 缓冲的字节流
对于面向字节的流,缓冲流通过将内存缓冲区附加到I/O系统来扩展过滤流。
这种流允许Java一次对多个字节执行多次I/O操作,从而提升性能。
因为可以使用缓冲区,所以略过、标记或重置流都是可能发生的。
缓冲的字节流类是BufferedInputStream和BufferedOutputStream。
PushbackInputStream也实现了缓冲流。

7.8.1 BufferedInputStream类
缓冲I/O是很常见的性能优化手段。Java的BufferedInputStream类允许将任何InputStream
对象封装到缓冲流中以提高性能。
BufferedInputStream类有两个构造函数:
BufferedInputStream(InputStream inputStream)
BufferedInputStream(InputStream inputStream,int bufSize)

使缓冲区大小等于内存页面、磁盘块等大小的整数倍,可以明显提高性能。
但这依赖于具体实现。
最优的缓冲区大小通常以来于宿主操作系统、可用的内存量以及机器的配置。
比较好的缓冲区大小大约是8192字节,并且对于I/O系统来说即使附加比较小的缓冲区,也
总是一个好主意。

除了任何InputStream都实现了的read()和skip()方法外,BufferedInputStream还支持mark()和reset()方法。

7.8.2 BufferedOutputStream类
除了增加了flush()方法之外,BufferedOutputStream与所有OutputStream类似,
flush()方法用于确保将数据缓冲区写入被缓冲的流中。
BufferedOutputStream是通过减少系统实际写数据的次数来提高性能的,因此可能需要调用
flush()方法,从而要求立即写入缓冲区的所有数据。
..与缓冲输入不同,缓冲输出没有提供附加功能。Java中用于输出的缓冲区只是为了
提高性能。下面是两个构造函数:
BufferedOutputStream(OutputStream outputStream)
BufferedOutputStream(OutputStream outputStream,int bufSize)
第一种形式使用默认缓冲区大小创建缓冲流。在第二种形式中,缓冲区是由bufSize传递的。

7.8.3 PushbackInputStream类
缓冲区的新应用之一就是回推(pushback)的实现。回推用于输入流,以允许读取字节,然后
再将他们返回(回推)到流中。PushbackInputStream类实现了这一思想,提供了一种机制,
可以“偷窥”来自输入流的内容而不对他们进行破坏。构造函数如下:
PushbackInputStream(InputStream inputStream)
PushbackInputStream(InputStream inputStream,int numBytes)
第一种形式创建的流对象允许将一个字节返回到输入流;
第二种形式创建的流对象具有一个长度为numBytes的回推缓冲区,从而允许将多个字节回
推到输入流中。
除了来自InputStream的方法,PushbackInputStream类还提供了unread()方法,如下所示:
void unread(int b)
void unread(byte[] buffer)
void unread(byte buffer,int offset,int numBytes)
第一种形式回推b的低字节,这会是后续的read()调用返回的下一个字节。
第二种形式回推buffer中的字节。
第三种形式回推buffer中从offset开始的numBytes个字节。
当回推缓冲区已满时,如果试图回推字节,就会抛出IOException异常。

警告:
PushbackInputStream对象会使得InputStream对象(用于创建PushbackInputStream 对象)的
mark()或reset()方法无效。对于准备使用mark()或reset()方法的任何流来说,都应当使用
markSupported()方法进行检查。

7.9 SequenceInputStream类
SequenceInputStream类允许链接多个InputStream对象。SequenceInputStream对象的构造与
其他所有InputStream对像都不同。SequenceInputStream构造函数使用一对InputStream对象
或InputStream对象的一个Enumeration对象作为参数:
SequenceInputStream(InputStream first, InputStream second)
SequenceInputStream(Enumeration<? extends InputStream> streamEnum)
在操作上,该类从第一个InputStream对象进行读取,直到读取完全部内容,然后切换到第二
个InputStream对象。对于使用Enumeration对象的情况,该类将持续读取所有InputStream
对象中的内容,直到到达最后一个InputStream对象的末尾为止。
当到达每个文件的末尾时,与之关联的流就会被关闭。
关闭通过SequenceInputStream创建的流,会导致关闭所有未关闭的流。

7.10 PrintStream类
PrintStream类提供了我们曾使用过的来自System文件句柄System.out的所有输出功能,这使得
PrintStream成为Java中最常用的类之一。
PrintStream类实现了Appendable、AutoCloseable、Closeable以及Flushable接口。
PrintStream类的构造函数:
PrintStream(OutputStream outputStream)
PrintStream(OutputStream outputStream,boolean autoFlushingOn)
PrintStream(OutputStream outputStream,boolean autoFlushingOn,String charSet)
throws UnsupportedEndingException
在此,outputStream指定了用于接收输出的打开的OutputStream对象。autoFlushingOn参数
控制每次写入一个换行符(\n)或字节数组,抑或调用println()方法时,是否自动刷新输出
缓冲区。如果autoFlushingOn为true,就自动刷新;如果为false,就不自动刷新。
第一个构造函数不自动刷新缓冲区。可以通过charSet传递的名称来指定字符编码。

下面几个构造函数提供了构造能够将输出写入文件中的PrintStream对象的简单方式:
PrintStream(File outputFile) throws FileNotFoundExeption
PrintStream(File outputFile,String charSet)
throws FileNotFoundException,UnsupportedEncodingException
PrintStream(String outputFileName) throws FileNotFoundException
PrintStream(String outputFileName,String charSet) throws FileNotFoundException,
UnsupportedEncodingException
这些构造函数从File对象或根据指定的文件名创建PrintStream对象。两种情况中,都会自动
创建文件。所有之前存在的同名文件都会被销毁。一旦创建PrintStream对象,就可以将所有
输出定向到指定的文件中。可以通过charSet传递的名称来指定字符编码。

注意:如果存在安全管理器,那么当发生安全性违规时,有些PrintStream构造函数会抛出
SecurityException异常。

PrintStream为所有类型(包括Object)都支持print()和println()方法。如果参数不是基本
类型,那么PrintStream方法会调用对象的toString()方法并显示结果。
从jdk5开始,Java为PrintStream类添加了printf()方法。该方法允许指定将要写入的数据的
精确格式。
printf()方法具有以下一般形式:
PrintStream printf(String fmtString,Object ... args)
PrintStream printf(Locale loc,String fmtString,Object ... args)

PrintStream类还定义了format()方法:
PrintStream format(String fmtString,Object ... args)
PrintStream format(Locale loc,String fmtString,Object ...args)

7.11 DataOutputStream类和DataInputStream类
通过DataOutputStream和DataInputStream类,可以向流中写入基本类型数据或从流中读取基本
类型数据。他们分别实现了DataOutput和DataInput接口,这些接口定义了将基本类型值转换
成字节序列或将字节序列转换成基本类型值的方法。

7.12 RandomAccessFile类
该类封装了随机访问文件的功能。
seek()方法用于设置文件指针在文件中的当前位置
void seek(long newPos) throws IOException

setLength()方法。


8 字符流

8.1 Reader类
Reader是抽象类,定义了Java的流字符输入模型。该类实现了AutoCloseable、Closeable以及
Readable接口。

8.2 Writer类
Writer是抽象类,定义了Java的流字符的输出模型,实现了AutoCloseable、Closeable、Flushable
以及Appendable接口。

8.3 FileReader类
FileReader类可以创建用于读取文件内容的Reader对象,构造函数:
FileReader(String filePath)
FileReader(File fileObj)
其中,filePath是文件的完整路径名,fileObj是描述文件的File对象。

8.4 FileWriter类
该类可以创建能够用于写入文件的Writer对象。

其他字符流与对应的字节流类似

9 Console类
JDK6将Console类添加到java.io包中,该类用于从控制台读取内容以及向控制台写入内容,
并且实现了Flushable接口。
Console类没有提供构造函数。相反,该类通过调用System.console()方法获取Console对象,
如下所示:
static Console.console()
如果控制台可用,就返回对控制台的引用;否则返回null。

10 串行化

10.1 Serializable接口
只有实现了Serializable接口的类才能够通过串行化功能进行保存和恢复。
Serizlizable接口没有定义成员,只是简单地用于指示类可以被串行化。如果一个类是可串行化的,
那么这个类的所有子类也收拾可串行化的。
声明为transient的变量不能通过串行化功能进行保存。
此外,也不能保存static变量。

10.2 Externalizable接口

10.3 ObjectOutput接口

10.4 ObjectOutputStream类

10.5 ObjectInput接口

10.6 ObjectInputStream类


猜你喜欢

转载自blog.csdn.net/qq_15720911/article/details/78151694