Java BIO,
Java BIO,
BIO是出现得比较陈旧的IO技术了,它的缺点在于并发量高时,IO操作等待的时间会比较长,因为它是阻塞IO。在IO中,一般按照数据的不同,可以分为字节流和字符流,字节流把读到的数据当做字节来处理,而字符流把数据当做字符来处理。
字节流
根据输入和输出,字节流又可以分为输入字节流InputStream和输出字节流OutputStream。
输入字节流InputSteam
这是一个Java接口,其原型如下:int read();//每次从字节流当前位置中读入一个字节
int read(byte[] buffer);//从字节流中当前位置开始读取数据今日到数值buffer中,最多读取buffer.length个字节
int read(byte[] buffer, int off, int len);//从字节流当前位置开指定的偏移off开始,读取len个字节到数组buffer中
int available();//返回字节流中可以读取的字节数
long skip(long a);//从字节流当前位置开始,跳过a个字节
void close();//关闭字节输入流
该接口还有许多实现类 ByteArrayInputStream:把一个byte[]当做输入流源 FileInputStream:把一个File对象当做输入流源 ObjectInputStream:把一个Java对象当做输入流源 StringBufferInputStream:把一个String对象当做输入流源 并且有这其他的三种特殊实现: PipedInputStream:实现了管道的,主要在线程中使用。 SequenceInputStream:把多个InputStream合并为一个InputStream。 FilterInputStream:对输入流进行各种过滤操作。
- ByteArrayInputStream
ByteArrayInputStream(byte[] src);
ByteArrayInputStream(byte[] src, int off, int len);
两个构造器都需要一个byte[]作为源。这个类可以直接操作byte[]。
public static void main(String[] args) {
// TODO Auto-generated method stub
byte[] src = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
ByteArrayInputStream is = new ByteArrayInputStream(src);
while(is.available() > 0)
{
int num = is.read();
System.out.print(num);
}
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- FileInputStream
FileInputStream(File file);
这个实现类用得是相当多,因为文件IO其实用得是非常多的。
public static void main(String[] args) {
// TODO Auto-generated method stub
File file = new File("test.txt");
if(file.exists())
{
try {
FileInputStream is = new FileInputStream(file);
byte[] buffer = new byte[1024];//缓冲区
int len = -1;
while((len = is.read(buffer, 0, buffer.length)) != -1)
{
System.out.println(new String(buffer, 0 , len));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- ObjectInputStream
ObjectInputStream(InputStream is);
通常来说,一个序列化的对象被写到了磁盘上,也算是一个文件了,所以通常的InputStream会采用其子类FileInputStream作为实际的参数。
public static void main(String[] args) {
// TODO Auto-generated method stub
File file = new File("person.txt");
if(file.exists())
{
FileInputStream is1;
try {
is1 = new FileInputStream(file);
ObjectInputStream is2 = new ObjectInputStream(is1);
Object obj = is2.readObject();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
- StringBufferInputStream
这个类使用字符创String作为源,它的构造器如下
StringBufferInputStream(String src);
这个类已经过时了,不推荐使用。
public static void main(String[] args) {
// TODO Auto-generated method stub
String src = "hello,world";
StringBufferInputStream is = new StringBufferInputStream(src);
byte[] buffer = new byte[is.available()];
try {
is.read(buffer);
System.out.println(new String(buffer));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
- PipedInputStream
管道输入流,该输入流需要从管道处获取数据。它的构造器如下
PipedInputStream(PipedOutputStream os);
PipedInputStream();
第一个构造器将使用管道输出流作为源,第二个构造器将创建一个无源的输入流。
- SequenceInputStream
该类可以将两个个InputStream串联起来。它的构造器如下
SequenceInputStream(InputStream is1, InputStream is2);
SequenceInputStream(Enumeration<? extends InputStream> e);
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
FileInputStream is1 = new FileInputStream(new File("src/a.txt"));
FileInputStream is2 = new FileInputStream(new File("src/b.txt"));
FileInputStream is3 = new FileInputStream(new File("src/c.txt"));
Vector<InputStream> v = new Vector<InputStream>();
v.add(is1);
v.add(is2);
v.add(is3);
SequenceInputStream sis = new SequenceInputStream(v.elements());
System.out.println(sis.available());
int i = -1;
while((i = sis.read()) != -1)
{
System.out.print((char)i);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
注意,这里不能使用available()来判断流的可用数据,而是需要判断是否到流的尾部read()是否==-1,才能将合并后的数据全部输出来。
- 过滤输入流FilterInputStream
它把其他的流作为基本数据源,FilterInputStream会将所有请求传递给包含InputStream的所有方法。这个类本身对于数据流没有什么用,它的子类DataInputStream和PushBackInputStream倒是蛮有用的。
DataInputStream
这个类可以将一些字节数据读取出来并转化成为基本的Java类型
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
byte[] src = new byte[]{1,1};
ByteArrayInputStream is = new ByteArrayInputStream(src);
DataInputStream dis = new DataInputStream(is);
short s = dis.readShort();
System.out.println(s);
}
PushBackInputStream
这个类可以有推回或者取消读取一个字节的能力,使用unread()方法可以让游标重新回到上一个读取过了的字节处。
字节输出流OutputStream
字节输入流负责字节流的取得,而字节输出流则负责字节的输出。
OutputStream是一个接口,它有着以下的一些实现类:
ByteArrayOutputStream
FileOutputStream
StringBufferOutputStream
ObjectOutputStream
此外,还有特殊的实现
PipedOutputStream
SequenceOutputStream
FilterOutputStream
- ByteArrayOutputStream
该类可以将字节流输出到字节数组里面
- FileOutputStream
该类可以将字节流输出到文件里面
- StringBufferOutputStream
该类可以将字节流输出到字符串里面
- ObjectOutputStream
该类可以将序列化对象输出
字符流
字符输入流Reader
Reader是一个接口,其原型如下:int read(char[] chs, int off, int len);//从字符流当前位置开始,将字符流读入到字符数组chs中,从off偏移位置开始存放,读入的字符流长度为len
int read();//从字符流当前位置开始,一次读取一个字符
int read(char[] chs);//从字符流当前位置开始,将字符流读入存放到chs字符数组中
boolean ready();//判断该流是否准备好
void reset();//重置流的位置
long skip(long n);//从字符流当前位置开始,跳过n个字符
void mark(int n);//对流进行标记
void colse();//关闭流
Reader有许多相关的实现类: CharArrayReader StringReader InputStreamReader BufferReader FilterReader PipedReader
- CharArrayReader
CharArrayReader(char[] src);
CharArrayReader(char[] src, int off, int len);
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
char[] src = new char[]{'h', 'e', 'l', 'l', 'o'};
CharArrayReader reader = new CharArrayReader(src);
int i = -1;
while((i = reader.read()) != -1)
{
System.out.print((char) i);
}
}
- StringReader
StringReader(String src);
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
String src = new String("hello");
StringReader reader = new StringReader(src);
int i = -1;
while( (i = reader.read()) != -1)
{
System.out.print((char) i);
}
}
InputStreamReader
该类以InputStream作为源,从InputStream中读入字符流,其构造器
InputStreamReader(InputStream is);
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
File file = new File("src/a.txt");
if(file.exists())
{
FileInputStream is = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(is);
int i = -1;
while( (i = reader.read()) != -1)
{
System.out.print((char) i);
}
}
}
适合用于读取一些全是字符的文件。这个类还有一个子类FileReader,FileReader是以文件作为源,从文件中读取字符流的,其构造器
FileReader(String filename);
FileReader(File file);
- PipedReader
PipedReader(PipedWriter writer);
- BufferReader
BufferedReader(Reader r);
BufferedReader(Reader r, int size);
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
File file = new File("src/a.txt");
if(file.exists())
{
FileInputStream is = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(is);
BufferedReader r = new BufferedReader(reader);
int i = -1;
while( (i = r.read()) != -1)
{
System.out.print((char) i);
}
}
}
- FilterReader
字符输出流Writer
Writer是一个接口,其原型如下:write(String str);
write(String str, int off, int len);
write(char[] chs);
write(char[] chs, int off, int len);
write(int i);
void flush();
void close();
其实现类如下: CharArrayWriter StringWriter OutputStreamWriter PrintWriter PipedWriter BufferedWriter
- CharArrayWriter
- StringWriter
- OutputStreamWriter
OutputStreamWriter(OutputStream os);
该类还有一个子类FileWriter,可以向文件输出字符,其构造器
FileWriter(String filename);
FileWriter(File file);
- PrintWriter
PrintWriter(OutputStream os)
- PushBackWriter
该类可以回退一个字符。
标准输入输出流
标准输入流System.in
这是一个InputStream对象标准输出流System.out
这是一个OutputStream对象字节流转换流InputStreamReader和OutputStreamWriter
这两个字符流可以将字节流转换,然后以字符流形式输入或者输出到目标。相关文章
- 暂无相关文章
用户点评