字节流
Java
把不同类型的输入、输出抽象为流
stream
,分为输入流和输出流,用统一的接口来表示
Java
开发环境中提供了包
java.io
,其中包括一系列的类来实现输入/输出处理
InputStream
是所有字节输入流的祖先,而
OutputStream
是所有字节输出流的祖先
具体子类:
ByteArrayInputStream, FileInputStream, FilterInputStream, ObjectInputStream,
PipedInputStream, SequenceInputStream, StringBufferInputStream
InputStream
InputStream
类是一个抽象类,方法包括:
int read()
int read(byte[])
int read(byte[],int,int)
void close()
关闭流
int available()
报告流中直接可读的字节数
skip(long)
跳过流中指定的字节
OutputStream
OutputStream
也是一个抽象类。它的主要方法包括:
void write(int)
void write(byte[])
void write(byte[],int,int)
其中第一个方法的
int
型的参数对应要写入的字节,后两个方法的参数与
InputStream
类似。
void close()
关闭输出流
void flush()
强行将写入缓冲区中剩余的数据写入
基本输入输出方法
System
类是
Java
语言中一个功能强大、非常有用的类,它提供了标准输入
/
输出及运行时的系统信息
System
类不能创建对象,也就是说,
System
类的所有属性和方法都是静态的,引用时要以
System
作为前缀
System.in
与
System.out
是
System
类的两个静态属性,分别对应了系统的标准输入
/
输出流
System
类管理标准输入输出流和错误流
System.out
:把输出送到缺省的显示
(
通常是显示器
)
,是
PrintStream
的对象
System.in
:从标准输入获取输入
(
通常是键盘
)
,是
InputStream
的对象
System.err
:把错误信息送到缺省的显示,是
PrintStream
的对象
同时使用
System.out
和
System.err
输出信息不能保证显示顺序就是执行顺序,为了避免这种情况在测试
代码执行中经常使用
System.err
输出
InputStream
基本输入类
InputStream
类是基本的输入类。它定义了所有输入流所需的方法。
public abstract int read() throws IOException
读取一个字节并以整数的形式返回,
0-255
。如果
返回
-1
已到输入流的末尾。
public int read(byte b[]) throws IOException
读取一系列字节并存储到一个数组,返回实际读取的
字节数。如果已经读到输入流的末尾则返回
-1
public void close() throws IOException
关闭输入流并释放资源
public int read(byte b[],int offset,int length) throws IOException
功能为从输入流中读数据。这一
方法有几种重载形式,可以读一个字节或一组字节。当遇到文件尾时,返回
-1
。最后一种形式中的
offset
是指把结果放在
b[]
中从第
offset
个字节开始的空间,
length
为长度
public long skip (long n) throws IOEnception
从输入流跳过几个字节。返回值为实际跳过的字节
数
OutputStream
基本输出类
三个重载形式都是用来向输出流写数据的
public abstract void write(int b)
向输入流写入一个字节数据,该字节为参数的低
8
位。
public void write(byte b[],int offset,int length)
将一个字节类型的数组中的从指定位置
offset
开始
的
length
个字节写入到输出流
public void close( )
关闭输出流,释放资源
public void write(byte b[])
将一个字节类型的数组中的数据写入到输出流
public void flush()
清除缓冲区,将缓冲区内尚未写出的数据全部输出
需求:使用字节流将一个文件进行拷贝
每次读写一个字节效率太低,所以使用字节数组。同时编码中需要考虑如果文件存在则进行拷贝操作,
否则提示文件不存在
要点
1
:从文件中读取数据放入到
buffer
字节数组中,如果文件中的内容大于
byte[]
,则最多读取
1024
个
字节;如果文件中数据不足,则实际有多少则读取多少;写入
buffer
数组默认是从
0
开始写入
,
最终返回
实际读取的字节数。如果读取到流末尾则返回
-1
要点
2
:不能直接写出数组,否则会有多余内容产生。可以使用
write(byte[],int,int)
保证只写出读取到的
内容
要点
3
:注意
try/finally
结构,
JDK1.7
中提供
Closeable
接口支持自动关闭,从而简化
try/finally
写法
字符流
在顶层有
Reader
和
Writer
两个抽象类。
Reader
和
Writer
中定义了
read()
和
write()
方法,它们被派生流类
重载
相关的子类
InputStreamReader
、
OutputStreamWriter
桥接流,用于自动实现字节流和字符流的转换
FileReader
、
FileWriter
文件流,用于实现针对文本文件的读写操作
CharArrayReader
、
CharArrayWriter
内存流,用于实现针对
char
数组的读写操作
PipedReader
、
PipedWriter
管道流,用于线程之间的通讯
FilterReader
、
FilterWriter
过滤流的父类
BufferedReader
、
BufferedWriter
缓存流,用于在流中添加缓冲区
StringReader
、
StringWriter
内存流,用于实现针对字符串的读写操作
字符流
Reader
int read()
读取一个字符并以整数的形式返回
0-65535
,如果返回
-1
则已到输入流末尾
int read(char[] cbuf)
读取一系列字符并存储到一个数组中,返回实际读取的字符数,如果读到输入
流末尾则返回
-1
void close()
关闭输入流并释放内存资源
int read(char[] cbuf, int off, int len)
读取
len
个字符并存储到一个数组中,从
off
位置开始,返回实
际读取的字符数,如果读取到输入流末尾则返回
-1
long skip(long n)
跳过
n
个字符不读,返回实际跳过的字节数
字符流
Writer
void write(int c)
将字符(
int
数组的低
8
位)压入到字符流中
void write(char[] cbuf, int off, int len)
将字符数组中的指定部分内容压入到字符流中,从
off
开始共
len
个字符
void write(String str)
将字符串中的内容压入到字符流中
void close()
关闭流并释放所占用的资源
void write(String str, int off, int len)
将字符串中的指定部分内容压入到字符流中,从下标
off
开始
共
len
个字符
void flush()
刷新缓冲区,将缓冲区中的数据全部送出到目标地,然后清空缓冲区
void write(char[] cbuf)
将字符数组中的所有数据压入到字符流中
一般来说:一次读写一个字符效率太低,可以引入
char[]
数组提高执行效率
小结
在学些
BIO
时记忆父类的方法,区分子类的实现不同
InputStream
中的方法
read(byte[]):int
;
Reader
中方法
read(char[]):int
如果到达流末尾
则
-1
OutputStream
中的方法
write(byte[],0,len):void
;
Writer
中的方法
write(char[],0,len)/write(String)
一般在使用中,如果读取数据使用字节流,则写出数据采用的也是字节流;不建议混用,除非引入
桥接流
文件流
FileInputStream("file-name") FileInputStream(File) FileNotFoundException
FileReader("file-name") FileReader(File) FileNotFoundException
FileOutputStream("file-name") FileOutputStream("file-name",true)
默认文件覆盖,如果
参数
true
表示追加
FileWriter("file-name") FileWriter("file-name",true)
一般不使用单字节或者单字符的操作方法,使用数组
注意:
try(){}
是推荐写法,否则应该使用
try{}finally{}
结构保证流的关闭
针对二进制文件不建议使用字符流,建议使用字节流进行操作,否则有可能拷贝文件出现问题: