IO流主要用于硬板、内存、键盘等处理设备上得数据操作,根据处理数据的数据类型的不同可以分为:字节流(抽象基类为InPutStream和OutPutStream)和字符流(抽象基类为Reader和Writer)。根据流向不同,可以分为:输入流和输出流。 其中主要结构可以用下图来表示:
(转自:http://blog.csdn.net/zzp_403184692/article/details/8057693)
字符流和字节流的主要区别:
1.字节流读取的时候,读到一个字节就返回一个字节; 字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。
2.字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。
(转自:http://blog.csdn.net/zzp_403184692/article/details/8057693)其他总结:
1、http://blog.csdn.net/whuhan2013/article/details/51539591
2、http://blog.csdn.net/u013087513/article/details/51956801
(字节-字符转换流)
3、http://blog.csdn.net/jinhongliang123/article/details/7931729 (通过“套接”图表示输入/输出原理)
(箭头貌似标反了)
一些代码:(根据 马士兵 视频整理)
import java.io.*;//流 需求包
import java.util.*;//Date类需求包
/*范例名称:
* 原文件名称:
* 要点:
* 1. 输入流、输出流 (相对程序来说)
* 2. (字节流 --1字节 InputStream/OutputStream vs 字符流 --2字节 Reader/Writer)
* 3. (节点流 vs 处理流--缓冲流、转换流、数据流、Print流、Object流)
*/
public class StreamTest {
public static void main(String[] args) {
// 创建文件
File dirCurrent = new File("");
String strCurrent = dirCurrent.getAbsolutePath();// 获取当前类的绝对路径
String pathStr = strCurrent + File.separator + "javaTest";// separator路径分隔符
String fileName = "test.txt";
File dirFile = new File(pathStr);
if (!dirFile.exists()) {
dirFile.mkdirs();// 创建目录
}
File file = new File(pathStr, fileName);
if (!file.exists()) {
try {
file.createNewFile();// 创建文件
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
// FileOutputStream(节点流)
String fileName2 = "test2.txt";
File file2 = new File(pathStr, fileName2);// 创建文件
if (!file2.exists()) {
try {
file2.createNewFile();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
FileInputStream in = null;
FileOutputStream out = null;
int b = 0;
try {
in = new FileInputStream(strCurrent + File.separator + "StreamTest.java");
out = new FileOutputStream(file2);
while ((b = in.read()) != -1) {
out.write((char) b);// 字节流
}
in.close();
out.close();
} catch (FileNotFoundException e) {
// TODO: handle exception
System.out.println("找不到指定文件");
System.exit(-1);
} catch (IOException e) {
// TODO: handle exception
System.out.println("文件复制错误");
System.exit(-1);
}
// Buffer缓冲流(处理流)
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
BufferedReader br = new BufferedReader(new FileReader(file));
String strTest = null;
for (int i = 0; i <= 10; i++) {
strTest = String.valueOf(Math.random());
bw.write(strTest);
bw.newLine();
}
bw.flush();// 使内存中的数据立刻写出
while ((strTest = br.readLine()) != null) {
System.out.println(strTest);
}
bw.close();// 关闭写缓冲区
br.close();// 关闭读缓冲区
} catch (IOException e) {
e.printStackTrace();
}
// 转换流
try {
// OutputStreamWriter字符流转字节流
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file, true), "ISO8859_1");// true表示追加
osw.write("Microsoft win7");// 直接写字符串进去啦
System.out.println(osw.getEncoding());
osw.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
/*
// 使用了2根“管道”读取键盘输入,然后输出显示
// InputStreamReader字节流转字符流
InputStreamReader isr = new InputStreamReader(System.in);
// BufferedReader的readLine好使
BufferedReader br = new BufferedReader(isr);
String s = null;
try {
System.out.println("请键盘输入字符串:回车结束");
// System.in是阻塞式
s = br.readLine();
while (s != null) {
if (s.equalsIgnoreCase("exit"))
break;
System.out.println(s.toUpperCase());
System.out.println("请键盘输入字符串:回车结束");
s = br.readLine();
}
br.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
*/
// 数据流 (先进先出)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);// 加 “管道”
try {
dos.writeDouble(Math.random());// 8字节
dos.writeBoolean(true);// 1字节
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
System.out.println(bais.available());// 剩余字节数
DataInputStream dis = new DataInputStream(bais);
System.out.println(dis.readDouble());
System.out.println(dis.readBoolean());
dos.close();
dis.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
// Print 流 (跟上边 “InputStreamReader字节流转字符流” 注释的部分 一次运行一个)
String strTemp = null;
BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));
try {
FileWriter fw = new FileWriter(file,true);// 追加
PrintWriter log = new PrintWriter(fw);//Print管道添加到file文件上
while ((strTemp = br2.readLine()) != null) {
if (strTemp.equalsIgnoreCase("exit"))
break;
System.out.println(strTemp.toUpperCase());
log.println("-----");
log.println(strTemp.toUpperCase());
log.flush();
}
log.println("===" + new Date() + "===");
log.flush();
log.close();
br2.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
//Object流(必须序列化相应的object)
T t=new T();
try{
FileOutputStream fos=new FileOutputStream(file,true);
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(t);//写Object流
oos.flush();
oos.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
//Serializable--标记化接口
class T implements Serializable{
int i=1;
int j=2;
double d=1.1;
transient int k=33;//序列化时不予考虑
}