1.流的概念
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。它的特性是进行数据传输;
2.流的分类
流按照流向数据流向可以分为输入流和输出流。
流按照处理数据类型的单位不同可以分为字节流和字符流。
3.字节流与字符流之间的区别:
1.读写单位不同:字节流式以字节(8位2进制)为单位,字符流是以字符为单位,根据码表映射字符,一次可能读多个字节。
2.处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
3.一次读入或读出是8位二进制。
4.字符流:一次读入或读出是16位二进制。
结论:只要是纯文本数据优先使用字符流,除此之外都使用字节流。
4.字节流的使用实例:
hello1文件内容:
示例代码1:
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream("hello1.txt");
fos=new FileOutputStream("hello2.txt");
byte[] bytes=new byte[5];
int a;
while((a=fis.read(bytes))!=-1) {
System.out.println("a:"+a);
fos.write(bytes);
};
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
打印结果:
hello2文件内容:
示例代码2:
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream("hello1.txt");
fos=new FileOutputStream("hello2.txt");
byte[] bytes=new byte[5];
int a;
while((a=fis.read(bytes,0,3))!=-1) {
System.out.println("a:"+a);
System.out.println("bytes:");
for(byte s:bytes) {
System.out.print(s+" ");
}
System.out.print('\n');
fos.write(bytes);
};
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
打印结果:
hello2文件内容:
示例代码3:
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream("hello1.txt");
fos=new FileOutputStream("hello2.txt");
byte[] bytes=new byte[5];
int a;
while((a=fis.read(bytes,0,3))!=-1) {
System.out.println("a:"+a);
System.out.println("bytes:");
for(byte s:bytes) {
System.out.print(s+" ");
}
System.out.print('\n');
fos.write(bytes, 0, a);//a为当次读到的字节个数
};
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
打印结果:
hello2文件内容:
示例4:
public static void main(String[] args) {
FileInputStream fis=null;
FileOutputStream fos=null;
try {
fis=new FileInputStream("hello1.txt");
fos=new FileOutputStream("hello2.txt");
byte[] bytes=new byte[5];
int a;
while((a=fis.read(bytes))!=-1) {
System.out.println("a:"+a);
fos.write(bytes,0,a);
};
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果:
hello2文件内容:
显然示例1,2都是错的,3,4是正确的。
总结:
read方法包括:
-
read(),此方法一个字节一个字节的读取,从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1 。
-
read (byte[] b),此方法按b进行读取,如果文件总共读取的byte长度是7,b长度为5,则读取2次,每次读取5个字节,最后一次读取2个字节。以整数形式返回实际读取的字节数。
-
read (byte[] b,int off,int len) 方法, 将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取的字节也可能小于该值。以整数形式返回实际读取的字节数。
write方法包括:(参照read方法)
write()
write (byte[] b) 在这里,和read方法不同的是,如果byte长度是7,则输出2次,每次读取5个字节,最后一次只有2个字节,却多出了3个字节,而采用第三种方法就可以避免你多余输出,占了内存。
write (byte[] b,int off,int len)
所以读尽量使用read (byte[] b),写则选择write (byte[] b,int off,int len)是最合适的。
5.缓冲流示例
public void test2() {
BufferedReader inR=null;
BufferedWriter outR=null;
try {
FileInputStream input=new FileInputStream("hello.txt");
InputStreamReader inI=new InputStreamReader(input,"UTF-8");//转换流(字节到字符)
inR=new BufferedReader(inI);
FileOutputStream output=new FileOutputStream("testWrite.txt");
OutputStreamWriter outI=new OutputStreamWriter(output,"UTF-8");//转换流(字节到字符)
outR = new BufferedWriter(outI);
String str=null;
while((str=inR.readLine())!=null) {
System.out.println(str);
outR.write(str);
outR.newLine();//换行
outR.flush();//刷新该流的缓冲
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}finally {
try {
if(inR!=null) {
inR.close();
}
if(outR!=null) {
outR.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果:
testWrite文件内容: