BIO是出現得比較陳舊的IO技術了,它的缺點在於併發量高時,IO操作等待的時間會比較長,因爲它是阻塞IO。在IO中,一般按照數據的不同,可以分爲字節流和字符流,字節流把讀到的數據當做字節來處理,而字符流把數據當做字符來處理。
字節流
根據輸入和輸出,字節流又可以分爲輸入字節流InputStream和輸出字節流OutputStream。
輸入字節流InputSteam
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
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
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();//關閉流
- 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
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
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
OutputStreamWriter(OutputStream os);
FileWriter(String filename);
FileWriter(File file);
- PrintWriter
PrintWriter(OutputStream os)
- PushBackWriter
該類可以回退一個字符。