流式IO
流(Stream)是字節的源或目的。

兩種基本的流是:輸入流(Input Stream)和輸出流(Output Stream)。可從中讀出一系列字節的對象稱為輸入流。而能向其中寫入一系列字節的對象稱為輸出流。
流的分類
節點流:從特定的地方讀寫的流類,例如:磁盤或一塊內存區域。
過濾流:使用節點流作為輸入或輸出。過濾流是使用一個已經存在的輸入流或輸出流連接創建的。
InputStream

三個基本的讀方法
abstract int read() :讀取一個字節數據,并返回讀到的數據,如果返回-1,表示讀到了輸入流的末尾。
int read(byte[] b) :將數據讀入一個字節數組,同時返回實際讀取的字節數。如果返回-1,表示讀到了輸入流的末尾。
int read(byte[] b, int off, int len) :將數據讀入一個字節數組,同時返回實際讀取的字節數。如果返回-1,表示讀到了輸入流的末尾。off指定在數組b中存放數據的起始偏移位置;len指定讀取的最大字節數。
其它方法
long skip(long n) :在輸入流中跳過n個字節,并返回實際跳過的字節數。
int available() :返回在不發生阻塞的情況下,可讀取的字節數。
void close() :關閉輸入流,釋放和這個流相關的系統資源。
void mark(int readlimit) :在輸入流的當前位置放置一個標記,如果讀取的字節數多于readlimit設置的值,則流忽略這個標記。
void reset() :返回到上一個標記。
boolean markSupported() :測試當前流是否支持mark和reset方法。如果支持,返回true,否則返回false。
java.io包中 InputStream的類層次
OutputStream

三個基本的寫方法
abstract void write(int b) :往輸出流中寫入一個字節。
void write(byte[] b) :往輸出流中寫入數組b中的所有字節。
void write(byte[] b, int off, int len) :往輸出流中寫入數組b中從偏移量off開始的len個字節的數據。
其它方法
void flush() :刷新輸出流,強制緩沖區中的輸出字節被寫出。
void close() :關閉輸出流,釋放和這個流相關的系統資源。
java.io包中 OutputStream的類層次
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo1:在控制臺讀取鍵盤輸入,然后顯示。Ctrl+C結束運行
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
int data;
7
8
while ((data = System.in.read()) != - 1 )
{
9
System.out.write(data);
10
}
11
12
}
13
14
}
15
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
基本的流類
1、FileInputStream和FileOutputStream
節點流,用于從文件中讀取或往文件中寫入字節流。如果在構造FileOutputStream時,文件已經存在,則覆蓋這個文件。
-------------------------------------------------------------------------------
Demo2:將字符串寫入特定文件,注意write方法只接收字符數組。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
FileOutputStream fos = new FileOutputStream( " 1.txt " );
7
8
/**/ /*
9
* 注意:FileOutputStream的write方法接收字符數組,不能接收String字符串,
10
* 所以要用String的getBytes方法生成一個字符數組
11
*/
12
fos.write( " http://www.cnblogs.com " .getBytes());
13
fos.close();
14
15
}
16
17
}
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
String的構造方法的API:
------------
Java API:
------------
String
public String(byte[] bytes,
int offset,
int length)
構造一個新的 String,方法是使用指定的字符集解碼字節的指定子數組。新的 String 的長度是一個字符集函數,因此不能等于該子數組的長度。
當給定字節在給定字符集中無效的情況下,該構造方法無指定的行為。當需要進一步控制解碼過程時,應使用 CharsetDecoder 類。
參數:
bytes - 要解碼為字符的字節
offset - 要解碼的首字節的索引
length - 要解碼的字節數
拋出:
IndexOutOfBoundsException - 如果 offset 和 length 參數索引字符超出 bytes 數組的范圍
從以下版本開始:
JDK1.1
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo3:將字符串寫入特定文件,注意write方法只接收字符數組。
然后通過文件輸出流讀取數據,注意使用String特定的構造方法。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
FileOutputStream fos = new FileOutputStream( " 1.txt " );
7
8
/**/ /*
9
* 注意:FileOutputStream的write方法接收字符數組,不能接收String字符串,
10
* 所以要用String的getBytes方法生成一個字符數組
11
*/
12
fos.write( " http://www.cnblogs.com " .getBytes());
13
fos.close();
14
15
// 使用String的這個構造方法:
16
// String(byte[] bytes, int offset, int length)
17
18
FileInputStream fis = new FileInputStream( " 1.txt " );
19
byte [] buf = new byte [ 100 ];
20
int len = fis.read(buf);
21
22
// 使用String的這個構造方法:
23
// String(byte[] bytes, int offset, int length)
24
System.out.println( new String(buf, 0 , len));
25
fis.close(); // 使用完后記得關閉文件流
26
27
}
28
29
}
30
31
-------------------------------------------------------------------------------
運行結果:http://www.cnblogs.com
-------------------------------------------------------------------------------
2、BufferedInputStream和BufferedOutputStream
過濾流,需要使用已經存在的節點流來構造,提供帶緩沖的讀寫,提高了讀寫的效率。
------------
Java API:
------------
構造方法摘要
BufferedOutputStream(OutputStream out)
創建一個新的緩沖輸出流,以將數據寫入指定的基礎輸出流。
BufferedOutputStream(OutputStream out, int size)
創建一個新的緩沖輸出流,以將具有指定緩沖區大小的數據寫入指定的基礎輸出流。
-------------------------------------------------------------------------------
BufferedOutputStream
public BufferedOutputStream(OutputStream out)
創建一個新的緩沖輸出流,以將數據寫入指定的基礎輸出流。
參數:
out - 基礎輸出流。
BufferedOutputStream
public BufferedOutputStream(OutputStream out,
int size)
創建一個新的緩沖輸出流,以將具有指定緩沖區大小的數據寫入指定的基礎輸出流。
參數:
out - 基礎輸出流。
size - 緩沖區的大小。
拋出:
IllegalArgumentException - 如果 size <= 0
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo4:通過一個OutputStream對象來構造一個BufferedOutputStream對象。
而FileOutputStream類是OutputStream類的子類,所以可以用它來構造。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
7
FileOutputStream fos = new FileOutputStream( " 1.txt " );
8
BufferedOutputStream bos = new BufferedOutputStream(fos);
9
bos.write( " http://www.cnblogs.com " .getBytes());
10
}
11
12
}
-------------------------------------------------------------------------------
運行結果:1.txt文件為空。原因:緩沖區沒有寫滿,程序沒有向文件寫數據。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
解決方法1:使用flush()方法:
-------------------------------------------------------------------------------
Demo4:使用flush()方法,可以使程序立即向文件寫數據。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
7
FileOutputStream fos = new FileOutputStream( " 1.txt " );
8
BufferedOutputStream bos = new BufferedOutputStream(fos);
9
bos.write( " http://www.cnblogs.com " .getBytes());
10
11
bos.flush();
12
}
13
14
}
-------------------------------------------------------------------------------
運行結果:數據被寫入相應的文件。
-------------------------------------------------------------------------------
解決方法2:使用close()方法:
-------------------------------------------------------------------------------
Demo5:使用close()方法,同樣可以使程序立即向文件寫數據。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
7
FileOutputStream fos = new FileOutputStream( " 1.txt " );
8
BufferedOutputStream bos = new BufferedOutputStream(fos);
9
bos.write( " http://www.cnblogs.com " .getBytes());
10
11
bos.close();
12
}
13
14
}
-------------------------------------------------------------------------------
運行結果:數據被寫入相應的文件。
-------------------------------------------------------------------------------
flush()和close()的區別:
還要使用流對象,還需要寫數據,使用flush(),否則使用close()。
另外,使用close()將關閉自己的流對象,同時會關閉與之相關的流對象,如FileOutputStream流。
-------------------------------------------------------------------------------
Demo6:使用BufferedInputStream流,從文件中讀取數據。
同樣要用InputStream流對象或者其子類的對象來構造。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
7
FileOutputStream fos = new FileOutputStream( " 1.txt " );
8
BufferedOutputStream bos = new BufferedOutputStream(fos);
9
bos.write( " http://www.cnblogs.com " .getBytes());
10
11
bos.close();
12
13
FileInputStream fis = new FileInputStream( " 1.txt " );
14
BufferedInputStream bis = new BufferedInputStream(fis);
15
byte [] buf = new byte [ 100 ];
16
int len = bis.read(buf);
17
18
// 使用String的這個構造方法:
19
// String(byte[] bytes, int offset, int length)
20
System.out.println( new String(buf, 0 , len));
21
bis.close();
22
}
23
24
}
-------------------------------------------------------------------------------
運行結果:輸出http://www.cnblogs.com
-------------------------------------------------------------------------------
3、DataInputStream和DataOutputStream
過濾流,需要使用已經存在的節點流來構造,提供了讀寫Java中的基本數據類型的功能。
------------
Java API:
------------
java.io
類 DataOutputStream
java.lang.Object
java.io.OutputStream
java.io.FilterOutputStream
java.io.DataOutputStream
所有已實現的接口:
Closeable, DataOutput, Flushable
public class DataOutputStream
extends FilterOutputStream
implements DataOutput
數據輸出流允許應用程序以適當方式將基本 Java 數據類型寫入輸出流中。然后,應用程序可以使用數據輸入流將數據讀入。
從以下版本開始:
JDK1.0
-------------------------------------------------------------------------------
構造方法摘要
DataOutputStream(OutputStream out)
創建一個新的數據輸出流,將數據寫入指定基礎輸出流。
-------------------------------------------------------------------------------
DataOutputStream
public DataOutputStream(OutputStream out)
創建一個新的數據輸出流,將數據寫入指定基礎輸出流。計數器 written 被設置為零。
參數:
out - 基礎輸出流,將被保存供以后使用。
-------------------------------------------------------------------------------
Demo7:使用DataOutputStream流,將基本數據類型以二進制形式寫入文件中。
同樣要用InputStream流對象或者其子類的對象來構造,
這里使用BufferedOutputStream對象來構造。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
7
FileOutputStream fos = new FileOutputStream( " dos.txt " ); // 獲得寫入文件功能
8
BufferedOutputStream bos = new BufferedOutputStream(fos); // 獲得緩沖功能
9
DataOutputStream dos = new DataOutputStream(bos); // 獲得寫入基本類型功能
10
11
/**/ /*
12
* 定義8種基本類型的對象
13
*/
14
byte b = 3 ;
15
short s = 4 ;
16
int i = 78 ;
17
long l = 100000 ;
18
char ch = ' a ' ;
19
boolean bl = false ;
20
float f = 4.5f ;
21
double d = 4.0001 ;
22
23
/**/ /*
24
* 將8種基本類型的對象寫入文件中
25
*/
26
dos.writeByte(b);
27
dos.writeShort(s);
28
dos.writeInt(i);
29
dos.writeLong(l);
30
dos.writeChar(ch);
31
dos.writeBoolean(bl);
32
dos.writeFloat(f);
33
dos.writeDouble(d);
34
dos.close();
35
}
36
37
}
-------------------------------------------------------------------------------
運行結果:8種基本類型的數據以二進制形式寫入指定的文件中。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo8:從指定的文件中讀取8種基本類型的數據
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class StreamDemo
{
4
5
public static void main(String[] args) throws Exception
{
6
7
FileOutputStream fos = new FileOutputStream( " dos.txt " ); // 獲得寫入文件功能
8
BufferedOutputStream bos = new BufferedOutputStream(fos); // 獲得緩沖功能
9
DataOutputStream dos = new DataOutputStream(bos); // 獲得寫入基本類型功能
10
11
/**/ /*
12
* 定義8種基本類型的對象
13
*/
14
byte b = 3 ;
15
short s = 4 ;
16
int i = 78 ;
17
long l = 100000 ;
18
char ch = ' a ' ;
19
boolean bl = false ;
20
float f = 4.5f ;
21
double d = 4.0001 ;
22
23
/**/ /*
24
* 將8種基本類型的對象寫入文件中
25
*/
26
dos.writeByte(b);
27
dos.writeShort(s);
28
dos.writeInt(i);
29
dos.writeLong(l);
30
dos.writeChar(ch);
31
dos.writeBoolean(bl);
32
dos.writeFloat(f);
33
dos.writeDouble(d);
34
dos.close();
35
36
FileInputStream fis = new FileInputStream( " dos.txt " );
37
BufferedInputStream bis = new BufferedInputStream(fis);
38
DataInputStream dis = new DataInputStream(bis);
39
System.out.println(dis.readByte());
40
System.out.println(dis.readShort());
41
System.out.println(dis.readInt());
42
System.out.println(dis.readLong());
43
System.out.println(dis.readChar());
44
System.out.println(dis.readBoolean());
45
System.out.println(dis.readFloat());
46
System.out.println(dis.readDouble());
47
dis.close();
48
}
49
50
}
-------------------------------------------------------------------------------
運行結果:數據正常輸出:
3
4
78
100000
a
false
4.5
4.0001
-------------------------------------------------------------------------------
4、PipedInputStream和PipedOutputStream
管道流,用于線程間的通信。一個線程的PipedInputStream對象從另一個線程的PipedOutputStream對象讀取輸入。要使管道流有用,必須同時構造管道輸入流和管道輸出流。
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 PipedInputStream
java.lang.Object
java.io.InputStream
java.io.PipedInputStream
所有已實現的接口:
Closeable
public class PipedInputStream
extends InputStream
傳送輸入流應該連接到傳送輸出流;傳送輸入流會提供要寫入傳送輸出流的所有數據字節。通常,數據由某個線程從 PipedInputStream 對象讀取,并由其他線程將其寫入到相應的 PipedOutputStream。不建議對這兩個對象嘗試使用單個線程,因為這樣可能會死鎖該線程。傳送輸入流包含一個緩沖區,可在緩沖區限定的范圍內將讀操作和寫操作分離開。
從以下版本開始:
JDK1.0
-------------------------------------------------------------------------------
------------
Java API:
------------
java.io
類 PipedOutputStream
java.lang.Object
java.io.OutputStream
java.io.PipedOutputStream
所有已實現的接口:
Closeable, Flushable
public class PipedOutputStream
extends OutputStream
傳送輸出流可以連接到傳送輸入流,以創建通信管道。傳送輸出流是管道的發送端。通常,數據由某個線程寫入 PipedOutputStream 對象,并由其他線程從連接的 PipedInputStream 讀取。不建議對這兩個對象嘗試使用單個線程,因為這樣可能會死鎖該線程。
從以下版本開始:
JDK1.0
-------------------------------------------------------------------------------
------------
Java API:
------------
connect
public void connect(PipedInputStream snk)
throws IOException
將此傳送輸出流連接到接收者。如果此對象已經連接到其他某個傳送輸入流,則拋出 IOException。
如果 snk 為未連接的傳送輸入流,而 src 為未連接的傳送輸出流,則可以通過以下任一調用使其連接:
src.connect(snk)
或:
snk.connect(src)
這兩個調用的效果相同。
參數:
snk - 要連接的傳送輸入流。
拋出:
IOException - 如果發生 I/O 錯誤。
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Demo9:利用管道輸入流和輸出流進行通訊。
-------------------------------------------------------------------------------
1
import java.io. * ;
2
3
public class PipedStreamDemo
{
4
5
public static void main(String[] args)
{
6
PipedOutputStream pos = new PipedOutputStream();
7
PipedInputStream pis = new PipedInputStream();
8
9
try
{
10
pos.connect(pis);
11
// pis.connect(pos); 二選一即可
12
13
new Producer(pos).start();
14
new Consumer(pis).start();
15
} catch (IOException e)
{
16
// TODO 自動生成 catch 塊
17
e.printStackTrace();
18
}
19
}
20
21
}
22
23
/**/ /*
24
* 生產者線程
25
*/
26
class Producer extends Thread
{
27
28
private PipedOutputStream pos;
29
30
public Producer(PipedOutputStream pos)
{
31
this .pos = pos;
32
}
33
34
public void run()
{
35
try
{
36
pos.write( " Hello, welcome you! " .getBytes());
37
pos.close();
38
} catch (Exception e)
{
39
e.printStackTrace();
40
}
41
}
42
43
}
44
45
/**/ /*
46
* 消費者線程
47
*/
48
class Consumer extends Thread
{
49
50
private PipedInputStream pis;
51
52
public Consumer(PipedInputStream pis)
{
53
this .pis = pis;
54
}
55
56
public void run()
{
57
try
{
58
byte [] buf = new byte [ 100 ];
59
int len = pis.read(buf);
60
System.out.println( new String(buf, 0 , len));
61
pis.close(); // 關閉輸入流
62
} catch (Exception e)
{
63
e.printStackTrace();
64
}
65
}
66
67
}
68
-------------------------------------------------------------------------------
運行結果:輸出Hello, welcome you!
-------------------------------------------------------------------------------
posted on 2006-08-24 18:41
CoderDream 閱讀(2008)
評論(1) 編輯 收藏 所屬分類:
Java基礎知識