Java入门笔记7_Stream
文章共 3 分页,当前第 1 页: [1] [2] [3] Z{A!ue!
/t@Lc;W
1. Streams及I/O Ze@,# M{
Stream就是信息源与目的地之间的通信路径,这里的信息源可以是文件、内存、网络等。Streams主要分为input及output Stream。 5iAFpe9<
9"ZP"O
1.1 InputStream类 \gRl&0V #
类InputStream处于Input stream类层次的最顶层,它主要具有以下几种方法: fxHQ iOqz
'.'%NEA
1.1.1 read方法 -@VpMnl
read方法用于从指定的输入流读取以字节为单位的数据,第一次从流的开始位置开始读取,以后每次从上次的结束部位开始读取,即自动实现了位移。 owL@Z 3c
= N-g"7
read方法有以下三种形态: 1UYb (T rQ
do>ySed
(1) int read(byte buff[n]):从指定输入流中读取n个字节填充到buff中,该方法返回读取的实际字节数,如果读取的实际字节数小于n,一般是因为已读到指定输入流的末尾; x9P?=1-{E
[%X db|m}
(2) int read():即不带参数,该方法每次一个字节从指定的输入流中读取数据。返回值也是int类型,但它并不代表读取的字节数,而是从流中读取的数据的本身,因数据本身是byte类型的,所以一般要强制进行转化;如果读到流的末尾返回的值是-1; eS4Q'Wk
m `%rqP
(3) int read(byte buff[n],int start, int len):从指定流读取数据,从start开始,填充len个字节到buff中,返回值为实际的填充数,如果返回值<len,一般表示已将指定流中的数据读完; O0Tw8<
*0z{[N
以下是read的简单例子: ycl0a_)p'y
@5![cX
import java.io.*; %J[U(:$
G8N |1fVe
class TestIO1{ !>K{z 4xP
;Z3ly <kp
public static void main(String args[]) { 11Yv&o g/
'y6_)_pI2
InputStream s = null; -*gL xf#
3u(UOt-L
try{ U4>c)FvD
%2 gklGh
s = new FileInputStream("io.txt"); 4g3qJ
;,1+? u
}catch(FileNotFoundException e){ Q!q D/`(0
x\o_8 gt;
System.out.println("file not find"); Z)j@(xu
`}]R73-ex
} [rE~Wy
6WAtTitx#
rnPS"ttG
"2{J?GR0
int i; Unn^9_?i
)%$ a7wl3
try{ /qc!;>6x-
/ nzjacC
i = s.read(); !<lU/_S\}
} {tFj
while(i != -1){ $ ZS~]{_W
%Fg}* 0
System.out.println((char)i); bfHB[
.i l`ahyL
i = s.read(); Ju (5l=Z
=#wF5)% <
} p`D;3fX
3 &y>
}catch(IOException e){ ?2Cy;(TEr
N'kjoysL`
System.out.println("io error"); cD|mP3]
$7b,l*{
} } } Ld_ 8bc
59l_@o;vj
1.1.2 skip方法 S on`n
skip方法类似于C语言中的lseek都是用于定位的。Skip方法定义:long skip(long n),该方法使指定流中的当前位置移动n个字节,n的值可以是负值用于向前移,skip方法返回值为实际移动的字节数,由于种种原因,如已到流尾或者其它原因返回的值往往小于n。对于读取文件来说,小于n的原因最大的原因是读到了文件尾。 p1 @-Fj9a
6_u?.Sm?"
1.1.3 available方法 C-r%IXzF
available方法用于计算指定流中当前有多少字节,如果指定的流是文件流,那么就返回文件的大小。Available返回的值是int类型。 R["4|SBr
;U{\=mTb
有的输入流可能没有能力返回字节数,如果对这些输入流使用avaiable方法,返回值为0。 J_,d4~&~
&ZK}FE?r{
1.1.4 close方法 NsB`9pi
对于打开的stream,Java可以自动回收,但是Java自动回收需要时间,所以最好自己调用close方法来关闭stream,这样方便下一次重新指定的流。 ^vLm.)x
TVp4NGBy
1.2 ByteArrayInputStream aity0#j}
ByteArrayInputStream是从InputStream中继承下来的,用于从字节数组中提取数据,关于ByteArrayInputStream的创建例子如下: E+3a&X@;xr
E%%d~/^fQz
byte[] buffer = new byte[1024]; XQ h.?Q=H
/d ?`9$2C
fillWithUsefulData(buffer); //自定义的方法,用于在buffer中填充数据 / Z~N\s
}cfC/XLE#`
InputStream s = new ByteArrayInputStream(buffer); +u3lra8+}
9=YXw| -
InputStream s1 = new ByteArrayInputStream(buffer,100,300); h nXk<FJ
U ^|j W:
其中ByteArrayInputStream(buffer,100,300)是创建到buffer的stream,从buffer的第100个字节开始取300字节。 b'~<KT ^
dZrW k
ByteArrayInputStream的其它方法与InputStream类似,这里不再重复。 Oq,Ah=
)q\5|{ KS
1.3 FileInputStream Z H0 7v
FileInputStream也是从InputStream中继承下来的,用于从指定的文件中提取。因此它的方法也与InputStream中的方法类似,这里不再介绍,只介绍FileInputStream中特殊的方法:getFD(),该方法用于获取文件句柄。使用方法如下: GI@'l
OYnS>(g
FileInputStream aFIS = new FileInputStream("aFileName"); y)8G}*;vgp
~ &vu7`D.
FileDescriptor myFD = aFIS.getFD(); ];c,M k
M9v.O+^d@1
这样以后要用到aFileName文件时可以使用myFD这个文件句柄(实际上是文件描述类的实例),如要重新打开该文件,可以使用FileInputStream aFIS = new FileInputStream(myFD)。 </oI2P<
_n/$H-t9G
关于文件描述类FileDescriptor,有以下几点说明: DT;'NS
i7@}k /*g
(1) 属性in:标准输入; `c?i=!X+
'vqqzB$
(2) 属性out:标准输出; WM*~i[|
S5 JbK={q
(3) 属性err:标准错误输出; +^ tZ
]xK#"!N8
在FileInputStream中还有另一个特殊的方法就是:finalize()。 9Wb/>q<DU:
>1*6s'Qu
1.4 FilterInputStream *sY`SV:Nn
FilterInputStream也是从InputStream中继承下来,不过FilterInputStream类基本上不能直接使用,一般上使用该类的派生类,如BufferedInputStream等。该类的最大特点是,在定义时可以嵌套: ?Q*8kaQB:=
8F'{U !xg
InputStream s = getAnInputStreamFromSomewhere(); ` XM" feb
E8@X;I
FilterInputStream s1 = new FilterInputStream(s); %foAWb l
~)x&se
FilterInputStream s2 = new FilterInputStream(s1); iwqIr M@J2
$kYod*OyO
FilterInputStream s3 = new FilterInputStream(s2); 1aXf/[+
/MlIY
所以该类的所有派生类都具有这个特性。 )+(&f%{c
\uZU\ '
1.5 BufferedInputStream R=kCW`+h#
BufferedInputStream指定数据源是内存的指定区域,从FilterInputStream继承下来的,这种类型的Stream主要用于提高性能,它定义时一般指定其它的InputStream,如: /.3,TqYb[v
Ht<Deqe))q
InputStream s = new BufferedInputStream(new FileInputStream("foo")); TR*Sv>t
L-{<TVy
BufferedInputSream是可以使用mark及reset方法,使用上述的嵌套方法间接的使其它的stream也支持这些方法了。 6 SXZM
Pqv_ory0_f
由于BufferedInputStream需要buffer,所以它需要等待在它之前的数据都到了后才工作,所以BufferedInputStream最好用在流的前面,如上面这个例子,当然用在最前面也没有什么意思了。 3."{nh:
6X09I@_o%
1.6 DataInputStream $,7pIZ(a'
DataInputStream也是从FilterInputStream继承下来的,所以也具有父类的特性。DataInputStream还implement DataInput接口,所以DataInputStream具体的方法最多,如:readShort、readBoolean、readByte、readUnsignedByte、readShort等。这些方法的都是read方法的扩展,使用上也相似,所以这里不多介绍。 mmO%`FB>K
%+adh~X
以下是readInt的实现: w7$BFTl-
^Iz07 f
public final int readInt() throws IOException { 3,_WzBAM
h9tKSc!
int ch1 = in.read(); JwcI~
p~vKbgu
int ch2 = in.read(); Ei@5@*/K
kj2$\1mT
int ch3 = in.read(); [8gfIe'Ki
|+(!M"
int ch4 = in.read(); gBMM
C1F RYv_
if ((ch1 | ch2 | ch3 | ch4) < 0) ?sPS(y,5
YZk pK*e
throw new EOFException(); 2RQF
xe8]pZ
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); ?uAw`v"X
B,#7.&5
} mAmVmy
GW" 9Kt1"
以下是readLine的实现: _69 "<AN%
7dLrw_#Ti
public final String readLine() throws IOException { i'.)4
r N/t-iaI
char buf[] = lineBuffer; 9 E\)p4
+Xh y+T
ak pBE ~]
i ?B*MUlQ
if (buf == null) { iW[Me_l
~!r4\
buf = lineBuffer = new char[128]; WoC%vA 2WR
4$*YdCO/m
} ~`.18t-
<*\TGC@;F
cal[t!q~
!nFPjoe
int room = buf.length; =3B^cTt6
}"r%0~
int offset = 0; t="G&{1
f_HIHS {
int c; rw(z@I
sFj-39by
-`|5xO7#
^V7[W;-Z
loop: while (true) { Cc>+);f
T}~<7`Fh
switch (c = in.read()) { -?6.8_'1
-5;D1
case -1: ufAR,_k
VB bW,!c
case '\n': je"#Q)SY|u
+V\ x
break loop; KbZc3{ndz
46UyW h}
:d6:F<Rq{
9'x6c.
case '\r': 3 skb=wU
D=U\O04D3N
int c2 = in.read(); &9a#FT0
+jMku!y&J
if ((c2 != '\n') && (c2 != -1)) { lo8\LTlx
r0[xn
if (!(in instanceof PushbackInputStream)) { Bl9Q33JE
t lb~Pe=
this.in = new PushbackInputStream(in); :cd3G3V~
e|A+VB+@5
} O4!Q66Nz
h8HJ$/
((PushbackInputStream)in).unread(c2); "luBc1bWM
WG iJJI>
} *kw<v:dk@
Q1UAwp
break loop; ?yt$xl<u
K-0gz P)Td
][!wN2? 62
j I{[7i
default: !D{*/X
rtM0 e^P
if (--room < 0) { .@);'T)`
q0W8v
buf = new char[offset + 128]; c.hpB
>** _e0;
room = buf.length - offset - 1; ]Pu>4=|
VuA'@toW:/
System.arraycopy(lineBuffer, 0, buf, 0, offset);
查看本文来源