0%

I/O流的总结-字节流

IO流(输入流,输出流)

字节流

InputStream

读一字节填充到int低8位:
int b = in.read();
读数据填充到字节数组:
in.read(byte[] buf);
in.read(byte[] buf,int start,int size);

OutputStream

写int的低8位写入到流:
out.write(int b)
将字节数组写入到流:
out.write(byte[] buf);
out.write(byte[] buf,int start,int size);

FileInputStream

FileInputStream是InputStream的子类
把文件作为字节流进行读操作
读取指定文件内容,按照16进制输出到控制台
每输出10个byte换行
单字节读取不适合大文件,大文件效率很低

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FileInputStream in = new FileInputStream(fileName);
int b ;//存储每次读到的一个字节
int i = 1;
while((b = in.read())!=-1){
if(b <= 0xf){
//单位数前面补0
System.out.print("0");
}
System.out.print(Integer.toHexString(b)+" ");
if(i++%10==0){
System.out.println();
}
}
in.close();

批量读取文件并输出,对大文件而言效率高:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
   FileInputStream in = new FileInputStream(fileName);
byte[] buf = new byte[8 * 1024];
int bytes = 0;//读到的字节的个数
int j = 1;
//一次可能读不满,只要读到数据,bytes就不可能是-1
while((bytes = in.read(buf,0,buf.length))!=-1){
for(int i = 0 ; i < bytes;i++){
System.out.print(Integer.toHexString(buf[i] & 0xff)+" ");
if(j++%10==0){
System.out.println();
}
}
}
in.close();

FileOutputStream

FileOutputStream是OutputStream的子类
将字节流写入文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//如果该文件不存在,则直接创建,如果存在,删除后创建
FileOutputStream out = new FileOutputStream("demo/out.dat");
out.write('A');//写出了'A'的低八位
out.write('B');//写出了'B'的低八位
int a = 10;//write只能写八位,那么写一个int需要些4次每次8位
out.write(a >>> 24);
out.write(a >>> 16);
out.write(a >>> 8);
out.write(a);
byte[] gbk = "中国".getBytes("gbk");
out.write(gbk);
out.close();

IOUtil.printHex("demo/out.dat");

DataOutputStream

对”流”功能的拓展,可以更方便地写int,long,double,char等,常见用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
String file = "demo/dos.dat";
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(file));
dos.writeInt(10);
dos.writeInt(-10);
dos.writeLong(10l);
dos.writeDouble(10.5);
//采用utf-8编码写出
dos.writeUTF("中国");
//采用utf-16be编码写出
dos.writeChars("中国");
dos.close();
IOUtil.printHex(file);

DataInputStream

常见用法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   String file = "demo/dos.dat";
IOUtil.printHex(file);
DataInputStream dis = new DataInputStream(
new FileInputStream(file));
int i = dis.readInt();
System.out.println(i);
i = dis.readInt();
System.out.println(i);
long l = dis.readLong();
System.out.println(l);
double d = dis.readDouble();
System.out.println(d);
String s = dis.readUTF();
System.out.println(s);

dis.close();

BufferedInputStream & BufferedOutputStream

这两个流类位IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IO的性能.
从应用程序中把输入放入文件,相当于将一缸水倒入到另一个缸中:
FileOutputStream.write()方法相当于一滴一滴地把水“转移”过去.
DataOutputStream.writeXxx()方法会方便一些,相当于一瓢一瓢把水“转移”过去.
BufferedOutputStream.write()方法更方便,相当于一瓢一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高了.
利用带缓冲的字节流, 进行文件的拷贝:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{
if(!srcFile.exists()){
throw new IllegalArgumentException("文件:"+srcFile+"不存在");
}
if(!srcFile.isFile()){
throw new IllegalArgumentException(srcFile+"不是文件");
}
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(srcFile));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(destFile));
int c ;
while((c = bis.read())!=-1){
bos.write(c);
bos.flush();//刷新缓冲区
}
bis.close();
bos.close();
}