文章出自:http://swiftlet.net/archives/1363
FileInputStream和FileOutputStream类属于字节类,可以操作任意类型的文件。在数据流的处理过程中,有两种情况。
(1)以单个字节的形式读写文件
(2)以数据块的形式读写文件
从JDK的源码中,我们可以看出来:
FileInputStream的读:
public
native
int
read
(
)
throws
IOException
;
private
native
int
readBytes
(
byte
b
[
]
,
int
off
,
int
len
)
throws
IOException
;
FileOutputStream的写:
public
native
void
write
(
int
b
)
throws
IOException
;
private
native
void
writeBytes
(
byte
b
[
]
,
int
off
,
int
len
)
throws
IOException
;
FileInputStream和FileOutputStream最常用的地方也就是文件的复制过程。下面通过两个例子来说明一下:
例子一:单个字节的读写
public
class
Test
{
public
static
void
main
(
String
[
]
args
)
{
File
src
=
new
File
(
"d:\\src.txt"
)
;
File
dst
=
new
File
(
"d:\\dst.txt"
)
;
doSaveFile
(
src
,
dst
)
;
}
public
static
void
doSaveFile
(
File
src
,
File
dst
)
{
InputStream
in
=
null
;
OutputStream
out
=
null
;
try
{
in
=
new
FileInputStream
(
src
)
;
out
=
new
FileOutputStream
(
dst
)
;
int
len
=
0
;
while
(
(
len
=
in
.
read
(
)
)
>
0
)
{
//len表示读取的字节
out
.
write
(
len
)
;
}
}
catch
(
Exception
e
)
{
}
finally
{
if
(
null
!=
in
)
{
try
{
in
.
close
(
)
;
}
catch
(
IOException
e
)
{
}
}
if
(
null
!=
out
)
{
try
{
out
.
close
(
)
;
}
catch
(
IOException
e
)
{
}
}
}
}
}
例子二:数据块的读写
public
class
Test
{
private
final
static
int
BUFFER_SIZE
=
16
*
1024
;
public
static
void
main
(
String
[
]
args
)
{
File
src
=
new
File
(
"d:\\src.txt"
)
;
File
dst
=
new
File
(
"d:\\dst.txt"
)
;
doSaveFile
(
src
,
dst
)
;
}
public
static
void
doSaveFile
(
File
src
,
File
dst
)
{
InputStream
in
=
null
;
OutputStream
out
=
null
;
try
{
in
=
new
FileInputStream
(
src
)
;
out
=
new
FileOutputStream
(
dst
)
;
byte
[
]
buffer
=
new
byte
[
BUFFER_SIZE
]
;
int
len
=
0
;
while
(
(
len
=
in
.
read
(
buffer
)
)
>
0
)
{
//len表示读取的字节数
out
.
write
(
buffer
,
0
,
len
)
;
}
}
catch
(
Exception
e
)
{
}
finally
{
if
(
null
!=
in
)
{
try
{
in
.
close
(
)
;
}
catch
(
IOException
e
)
{
}
}
if
(
null
!=
out
)
{
try
{
out
.
close
(
)
;
}
catch
(
IOException
e
)
{
}
}
}
}
}
疑问:
上面列出了两个例子,到底哪个例子的效率更高一些呢?
也许这个问题很难回答,因为效率的比对很难实现。而且数据流的底层实现,我们也很难搞清楚。其实,撇开这个问题,我们还有更高效的读取方式,那就是下一篇文章要讲的BufferedInputStream和BufferedOutputStream。
需要注意的是:
创建FileInputStream实例对象时,指定的文件应当是存在和可读的。创建FileOutputStream实例对象时,如果指定的文件已经存在,这个文件中的原来内容将被覆盖清除。