分类
分类一--介质:
- 底层流(面向介质)
- 装饰器流:功能增强
分类二--方向:
- 输入流
- 输出流
流注意事项
输出流
注意实现
- 关闭 close方法 finally 中关闭,或者 java 7的 try方式创建;
- 清除缓冲-flush,小成本方法,但是如果不调动,会造成缓冲区数据永远不输出;
输入流
- 部分可用(多字节read方法),由于网络延迟可能只读取部分数据,解决方案
int bytesRead=0; int bytesToRead=1024; byte[] input = new byte [bytesToRead]; while (bytesRead<bytesToRead) { int result = in.read(input,bytesRead,bytesToRead-bytesRead); if(result==-1)break; bytesRead = result; }
注意是 while是小于号
- 流结束:read方法返回-1,但是处理不好永远不会返回-1,available()方法的缺陷
InputStream in = null; int bytesAvailable = in.available(); byte[] input = new byte[bytesAvailable]; //如下 bytesAvailable 可能为0,但实际是流可能已经结束了,但是read却不会返回 -1 而是 0 int bytesRead = in.read(input,0,bytesAvailable);
- 阻塞:read()会阻塞
- 多字节read方法:read(byte b[], int off, int len),第三个参数len,如果为0,则不会判断流结束
无符号字节处理--read() :int 方法,对应输出流write(int b)
int i = b >=0 ?b : 256 + b;
流释放模式
java 7 之前
OutputStream out = null;
try {
out = new FileOutputStream("/tmp/data.txt");
// 处理流
} catch (Exception e) {
// 处理异常
}finally {
if(out!=null)
{
try {
out.close();
} catch (Exception e2) {
}
}
}
java 7 模式
try(OutputStream out = new FileOutputStream("/tmp/data.txt")) {
} catch (Exception e) {
// 处理异常
}
PrintStream三宗罪
- 第一个问题 println()的输出与平台有关,有时换行符,有时回车符,有时回车/换行符
- 第二个问题PrintStream假定使用所在平台的默认编码
- 第三个问题PrintStream吞掉了所有异常
总结:网络程序员应当像躲避瘟神一样避开它
数据流
DataInputSream和DataOutStream 可以用二进制读/写JAVA的基本类型和字符串,主要用于在两个Java进程之间交换数据
readLine()的问题:
第一 废弃
第二 存在bug