12. 流与文件 - core java 7
12.1 流
流是字节序列从源到目的的传送. 其源和目的可以是文件也可以是网络连接或内存块.
在Java中有很多流类.
InputStream
|
|-AudioInputStream
|-ByteArrayInputStream
|-FileInputStream //用来得到文件的输入流. 但读2进制数据应该用RandomAccessFile
|-PipedInputStream //管道流
|-SequenceInputStream
|-StringBufferInputStream
|-ObjectInputStream -----------> <<interface>> ObjectInput
|-FilterInputStream //流过滤器类. 构造器接收一个InputStream对象. 应该是装饰模式.
|-BufferedInputStream //使一个流称为带缓冲能力的流(缺省是不缓冲的).
|-CheckedInputStream //
|-CipherInputStream
|-DigestInputStream
|-LineNumberInputStream
|-ProgressMonitorInputStream
|-PushbackInputStream //它可以让流支持预读一个字节的功能.
|-DataInputStream //实现了DataInput接口. 所以有读取2进制数据的方法.
|-InflaterInputStream
|-GZIPInputStream
|-ZipInputStream
|-JarInputStream
OutputStream
|-ByteArrayOutputStream
|-FileOutputStream // //用来得到文件的输出流. 但写2进制数据应该用RandomAccessFile
|-PipedOutputStream //管道流
|-ObjectOutPutStream ------------> <<interface>>ObjectOutput
|-FilterOutputStream //流过滤器类
|-BufferedOutputStream //缓冲
|-CheckedOutputStream
|-CipherOutputStream
|-DigestOutputStream
|-PrintStream
|-DataOutputStream //实现了DataOutput接口. 所以有写入2进制数据的方法.
|-DeflaterOutputStream
|-GZIPOutputStream
|-ZipOutputStream
|-JarOutputStream
Reader
|-BufferedReader
| |-LineNumberReader
|
|-CharArrayReader
|-FilterReader
| |-PushbackReader
|
|-InputStreamReader
| |-FileReader
|
|-PipedReader
|-StringReader
Writer
|-BufferedWriter
|-CharArrayWriter
|-FilterWriter
|-PipedWriter
|-PrintWriter //用来输出文本流. 用它提供的print() println() 会很方便.
|-StringWriter
|-OutputStreamWriter
|-FileWriter
流分为输入流和输出流.
抽象类InputStream和Reader表示输入流. OutputStream和Writer表示输出流.
其中Reader和Writer输入/输出的是Unicode字符(16位).
4种流都实现了Closeable接口.所以有方法void close()throws IOException.
输出流OutputStream和Writer还实现了Flushable接口. 所以有方法void flush().
Reader类还实现了Readable接口. 所以有方法int read(CharBuffer cb).
Writer类还实现了Appendable接口.所以它有两个方法用来向流追加字符或字符序列.
InputStream类有方法:
abstract int read()throws IOException //抽象方法.读一个字节并将其返回.若读到末尾则返回-1.
//注意它可能阻塞当前线程.
int read(byte[] b) throws IOException //相当于调用下边的 read(b, 0, b.length)
int read(byte[] b, int off, int len) throws IOException
//尝试读入len字节. 存入b[off]开始的缓冲区中. 它读取的时候会调用int read()来依次读入每个
//字节. 若读第一个字节时导致read()抛出IOException则本函数也抛出IOException, 但在后续
//的调用中read()抛出的IOException会在本函数内被捕获而不会抛出来(此时函数会返回已经正确
//读出的字节数).
long skip(long n) throws IOException //跳过n字节. 返回实际跳过的字节数. 若n为负则不跳过.
int available() throws IOException //返回流中当前可以不受阻塞地读取(或跳过)的字节数。
void close() throws IOException //关闭并释放与该流关联的所有系统资源
OutputStream类的方法有:
abstract void write(int b) throws IOException//向流写入的是参数b的低8位.高24位被忽略.
void write(byte[] b) throws IOException //相当于write(b, 0, b.length)
void write(byte[] b, int off, int len) throws IOException
//向流中写入b[off]开始的len个字节.
void flush() throws IOException //刷新此输出流并强制写出所有缓冲的字节
void close() throws IOException //关闭此输出流并释放与此流有关的所有系统资源
Reader类的方法有:
int read() throws IOException //读取单个字符
int read(CharBuffer target) throws IOException
//试图将字符读入指定的字符缓冲区.返回读入的字符数.
int read(char[] cbuf) throws IOException //将字符读入数组. 返回读入的字符数.
abstract int read(char[] cbuf, int off, int len) throws IOException
//将字符读入cbuf[off]开始的地方
long skip(long n) throws IOException //跳过n个字符
boolean ready() throws IOException //若下一个read()不阻塞则返回True
boolean markSupported() //判断此流是否支持 mark() 操作
void mark(int readAheadLimit) throws IOException //标记流中的当前位置.和reset()合用.
void reset() throws IOException //重置该流到mark()处.若目前尚未mark或已实效则抛出异常.
void close() throws IOException //关闭该流
Writer类的方法:
void write(int c) throws IOException //写入单个char(即c的低16位).
void write(char[] cbuf) throws IOException //写入字符数组
void write(char[] cbuf, int off, int len) throws IOException //写入字符数组的一部分
void write(String str) throws IOException //写入字符串
void write(String str, int off, int len) throws IOException //写入字符串的一部分
Writer append(CharSequence csq) throws IOException //将字符序列追加到此 writer
Writer append(CharSequence csq, int start, int end) throws IOException
//将指定字符序列的子序列追加到此 writer
Writer append(char c) throws IOException //将指定字符追加到此 writer
void flush() throws IOException //刷新此流
void close() throws IOException //关闭此流
上边介绍的4种流类(InputStream,OutputStream,Reader,Writer)都是抽象类.
下边看看具体的实际使用的流类.
PrintWriter类
它派生于Writer类. 并且它也有和PrintStream中一样的print()/println()方法.
所以它用来方便的输出文本流.
构造方法:
PrintWriter(File file)
PrintWriter(OutputStream out)
PrintWriter(OutputStream out, boolean autoFlush)//第2个参数为是否自动刷新.缺省为否.
PrintWriter(String fileName)
PrintWriter(Writer out)
PrintWriter(Writer out, boolean autoFlush)
其它方法:
它继承自Writer.所以有Writer的write() append() 等方法.
并且还有以下的各种print方法:
void print(boolean b) //打印 boolean 值。
void print(char c)
void print(char[] s)
void print(double d)
void print(float f)
void print(int i)
void print(long l)
void print(Object obj)
void print(String s)
PrintWriter printf(Locale l, String format, Object... args)
//使用指定格式字符串和参数将格式化的字符串写入此 writer 的便捷方法。
PrintWriter printf(String format, Object... args)
//使用指定格式字符串和参数将格式化的字符串写入此 writer 的便捷方法。
void println() //通过写入行分隔符字符串终止当前行。
void println(boolean x)
void println(char x)
void println(char[] x)
void println(double x)
void println(float x)
void println(int x)
void println(long x)
void println(Object x)
void println(String x)
流经常和磁盘文件关联. 要得到一个文件的输入流或输出流用:
FileInputStream 和 FileOutputStream
这两个类用来得到一个磁盘文件的输入流或输出流.
这两个流从文件中读写文本内容很方便.但不能读写2进制数据.
它们继承自InputStream和OutputStream. 所以分别有read() / write()方法用来读写文本.
构造方法(若文件无法打开抛出FileNotFoundException):
FileInputStream(File file)
FileInputStream(FileDescriptor fdObj)
FileInputStream(String name)
FileOutputStream(File file)
FileOutputStream(File file, boolean append) //若append为True则写入时写入文件末尾.
FileOutputStream(FileDescriptor fdObj)
FileOutputStream(String name)
FileOutputStream(String name, boolean append)
这两个类得到的流是字节流.要得到字符(16位)流可以用对应的FileReader类和FileWriter类.
不过FileInputStream / FileOutputStream 以及 FileReader / FileWriter都不能读写2进制的数据.
所以就需要下边的RandomAccessFile(随机存取文件流)类:
2进制IO
先看看2进制流类的接口:
<<interface>>DataInput -|
|- RandomAccessFile
<<interface>>DataOutput-|
其中接口DataInput是2进制输入流的接口. 方法有:
boolean readBoolean() //读取一个输入字节,如果该字节不是零,则返回 true
byte readByte() //读取并返回一个输入字节。
char readChar() //读取一个输入的 char 并返回该 char 值。
double readDouble() //读取八个输入字节并返回一个 double 值。
float readFloat() //读取四个输入字节并返回一个 float 值。
void readFully(byte[] b) //从输入流中读取一些字节,并将它们存储到缓冲区数组 b 中。
void readFully(byte[] b, int off, int len) //从输入流中读取 len 个字节。
int readInt() //读取四个输入字节并返回一个 int 值。
String readLine() //从输入流中读取下一文本行。
long readLong() //读取八个输入字节并返回一个 long 值。
short readShort() //读取两个输入字节并返回一个 short 值。
int readUnsignedByte() //读取一个输入字节,将它左侧补零 (zero-extend) 转变为 int 类型,
//并返回结果,所以结果的范围是 0 到 255。
int readUnsignedShort() //读取两个输入字节,并返回 0 到 65535 范围内的一个 int 值。
String readUTF() //读入一个已使用 UTF-8修改版格式编码的字符串。该格式根据字符的大小用
//1到3个字节存储字符
int skipBytes(int n) //试图在输入流中跳过数据的 n 个字节,并丢弃跳过的字节。
接口DataOutput是2进制输出流的接口. 方法有:
void write(byte[] b) //将数组 b 中的所有字节写入输出流。
void write(byte[] b, int off, int len) //将数组 b 中的 len 个字节按顺序写入输出流。
void write(int b) //将参数 b 的八个低位写入输出流。
void writeBoolean(boolean v) //将一个 boolean 值写入输出流。
void writeByte(int v) //将参数 v 的八个低位写入输出流。
void writeBytes(String s) //将一个字符串写入输出流。
void writeChar(int v) //将一个 char 值写入输出流,该值由两个字节组成。
void writeChars(String s) //将字符串 s 中的所有字符按顺序写入输出流,每个字符用两字节表示
void writeDouble(double v) //将一个 double 值写入输出流,该值由八个字节组成。
void writeFloat(float v) //将一个 float 值写入输出流,该值由四个字节组成。
void writeInt(int v) //将一个 int 值写入输出流,该值由四个字节组成。
void writeLong(long v) //将一个 long 值写入输出流,该值由八个字节组成。
void writeShort(int v) //将两个字节写入输出流,用它们表示参数值。
void writeUTF(String str) //将表示长度信息的两个字节写入输出流,
//后跟字符串 s 中每个字符的 UTF-8 修改版表示形式。
//该格式根据每个字符的值来用1到3个字节表示
随机存取文件流 RandomAccessFile
这个类实现了 DataInput 和 DataOutput 两个接口. 它可以读写文本内容或2进制内容
它的构造器
RandomAccessFile(String name, String mode)
public RandomAccessFile(File file, String mode)
的第2个参数可以是"r"或"rw" . 分别表示"只读"或"读写".
随机读取文件类有一个文件指针. 可以检查/设置此文件指针来随机读写:
long getFilePointer() //返回此文件中文件指针的当前偏移量
void seek(long pos) //设置到此文件指针的偏移量
检查/设置文件长度用:
long length() //返回此文件的长度
void setLength(long newLength) //设置此文件的长度
读写数据使用DataInput和DataOutput接口中声明的方法.以及下边几个read方法:
int read() //读取一个数据字节。
int read(byte[] b) //将最多 b.length 个数据字节从此文件读入字节数组。
int read(byte[] b, int off, int len)
上边的RandomAccessFile类的构造方法的参数是File类的对象.
这个File类是什么? 就是一个抽象的路径名. 下边我们看这个类
File类
这个类表示文件和目录. 它只是一个抽象的路径名. 并不能用它来读写数据.
构造方法:
File(File parent, String child) //用parent和child字符串创建一个新的File实例。
File(String pathname) //将给定字符串转换成抽象路径名来创建一个新 File 实例。
File(String parent, String child) //用parent字符串和child字符串创建一个新File实例。
File(URI uri) //将给定的 file: URI 转换成一个抽象路径名来创建一个新的 File 实例。
其它方法:
static File[] listRoots() //列出可用的文件系统根目录。
static File createTempFile(String prefix, String suffix)
//在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
static File createTempFile(String prefix, String suffix, File directory)
//在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
boolean canRead() //是否可以读取此抽象路径名表示的文件。
boolean canWrite() //是否可以修改此抽象路径名表示的文件。
int compareTo(File pathname) //按字母顺序比较两个抽象路径名。
boolean createNewFile() //当且仅当不存在具有此抽象路径名指定的名称的文件时
//原子地创建由此抽象路径名指定的一个新的空文件。
boolean delete() //删除此抽象路径名表示的文件或目录。
void deleteOnExit() //在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
boolean equals(Object obj)
boolean exists() //测试此抽象路径名表示的文件或目录是否存在。
File getAbsoluteFile() //返回抽象路径名的绝对路径名形式。
String getAbsolutePath() //返回抽象路径名的绝对路径名字符串。
File getCanonicalFile() //返回此抽象路径名的规范形式。
String getCanonicalPath() //返回抽象路径名的规范路径名字符串。
String getName() //返回由此抽象路径名表示的文件或目录的名称。
String getParent() //返回此抽象路径名的父路径名的路径名字符串
//如果此路径名没有指定父目录,则返回 null。
File getParentFile() //返回此抽象路径名的父路径名的抽象路径名
//如果此路径名没有指定父目录,则返回 null。
String getPath() //将此抽象路径名转换为一个路径名字符串。
int hashCode() //计算此抽象路径名的哈希码。
boolean isAbsolute() //是否为绝对路径名
boolean isDirectory() //是否是一个目录
boolean isFile() //是否是一个标准文件
boolean isHidden() //是否是一个隐藏文件
long lastModified() //最后一次被修改的时间
long length() //表示的文件的长度。
String[] list() //目录中的文件和目录的名称所组成字符串数组。
String[] list(FilenameFilter filter) //目录中的文件和目录的名称所组成的字符串数组
//这一目录是通过满足指定过滤器的抽象路径名来表示的
File[] listFiles() //和上边的方法类似. 返回目录下所有子目录和文件的File对象
File[] listFiles(FileFilter filter)
File[] listFiles(FilenameFilter filter)
boolean mkdir() //创建此抽象路径名指定的目录。
boolean mkdirs() //创建此抽象路径名指定的目录,若它的父目录不存在则一起创建之
boolean renameTo(File dest) //重新命名此抽象路径名表示的文件。
boolean setLastModified(long time) //设置文件或目录的最后一次修改时间。
boolean setReadOnly() //使该文件或目录只读
String toString() //返回此抽象路径名的路径名字符串。
URI toURI() //构造一个表示此抽象路径名的 file: URI。
URL toURL() //将此抽象路径名转换成一个 file: URL。
/////////////////////// 未完 待续 ////////////////////////
管道流
PipedOutputStream
PipedInputStream
它们可以在不同的线程间传递数据. 跳过~~~~~ 以后看~~~
27.7 字节数组流 -Java2详解
ByteArrayInputStream 和 ByteArrayOutputStream
流并不总是和文件关联呀. 也可以和一个内存缓冲区关联.
而这两个类就是提供这样的功能. 它类似于c++STL中的 istringstream 和 ostringstream .
构造方法:
ByteArrayInputStream(byte[] buf) //使用 buf 数组作为其缓冲区。
ByteArrayInputStream(byte[] buf, int offset, int length)
//只能从缓冲流读length字节. 这两个构造方法得到的流的缓冲区就是buf数组而不是buf的拷贝.
ByteArrayOutputStream() //创建新的字节数组输出流。
ByteArrayOutputStream(int size) //参数size指定缓冲区的容量(字节数).
其他方法:
ByteArrayInputStream只有其父类InputStream中声明的方法.
而ByteArrayOutputStream类的方法有:
void reset() //清空输出流中目前已累积的所有输出
int size() //返回缓冲区的当前已经写入的字节数。
byte[] toByteArray() //返回输出的流的字节数组表示. 该字节数组是新分配的.
String toString() //将缓冲区的内容转换为字符串
//根据平台的默认字符编码将字节转换成字符。
String toString(String enc) //参数为转换为字符串时使用的字符编码
void write(byte[] b, int off, int len)
//将指定字节数组中从偏移量 off 开始的 len 个字节写入此字节数组输出流。
void write(int b) //将指定的字节(b的低8位)写入此字节数组输出流
void writeTo(OutputStream out) //将流的内容写入到参数指定的输出流中
27.8 字符数组流 -Java2详解
CharArrayReader 和 CharArrayWriter
这两个类是上边 ByteArrayInputStream 和 ByteArrayOutputStream 的字符(16位)版本.
功能和方法很类似. 构造方法为:
CharArrayReader(char[] buf)
CharArrayReader(char[] buf, int offset, int length)
CharArrayWriter()
CharArrayWriter(int size)
27.10 StringBufferInputStream
这个类和ByteArrayInputStream的功能类似. 区别是ByteArrayInputStream的构造方法的参数是
Byte[] 而 StringBufferInputStream 构造方法的参数是 String :
构造方法:
StringBufferInputStream(String str)
27.9 字节流到字符流的转换 -Java2详解
要让字节流(8位)转换为字符流(16位). 使用下边两个类:
InputStreamReader 和 OutputStreamWriter
它们是Reader和Writer的子类. 但它们的参数却是InputStream和OutputStream.
这样就可以用一个字节流来构造一个字符流. 并使用字符流Reader/Writer的方法读写.
它们的构造方法如:
InputStreamReader(InputStream in)
OutputStreamWriter(OutputStream out)
它们还有其它构造方法用以指定字符流到字节流转换使用的编码.
27.4.7 流过滤器类 FilterInputStream -Java2详解
下边是一些流的过滤器类.它们派生自FilterInputStream.
它们的构造方法都是接收一个InputStream对象. 所以可以有很多层这样的过滤器. 应该是装饰模式.
27.5 缓冲区例的流 -Java2详解
BufferedInputStream / BufferedOutputStream
是流过滤器类. 派生于FilterInputStream / FilterOutputStream .
它们使输入/输出流具有缓冲能力. 提高性能.
BufferedInputStream在调用read()方法时会将尽可能多的数据读入缓冲区.
BufferedOutputStream则是只有在缓冲区写满或调用flush方法时才调用write()方法.
构造方法:
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in, int bufferSize) //指定缓冲大小
BufferedOutputStream(OutputStream in)
BufferedOutputStream(OutputStream in, int bufferSize)
27.6 数据流 -Java2详解
DataInputStream 和 DataOutputStream
是流过滤器类. 派生于FilterInputStream / FilterOutputStream .
并且它们还实现了 DataInput接口 / DataOutput接口.
所以当读写2进制数据的时候. 需要用这种流过滤器. 它拥有readInt()/writeDouble()这样的方法.
它们的构造器为:
DataInputStream(InputStream in)
DataOutputStream(OutputStream out)
27.11 对象流
为了直接读写一个类对象. 提供了 ObjectInput 接口和 ObjectOutput 接口.
ObjectInput接口扩展了DataInput接口.并添加了唯一的方法:
Object readObject() throws ClassNotFoundException, IOException
ObjectOutput接口扩展了DataOutput接口. 并添加了唯一的方法:
void writeObject(Object obj) throws IOException
猴子的神啊 Java的流类很多. 饿吃饭先~~~~~~