IO 流
在 java 中流可类比为一个个数据的序列,所以在流中常用 byte[] 或char[]用作传输数据的小车,推荐使用 4096(就是 4k 大小)作为传输一个流大小,当流的大小特别大时应使用 BufferedReader / BufferedWriter 做流的传输小车以提高效率,输入流表示从源读取数据(例如从硬盘文件读数据到内存中),输出流表示向一个目标写入数据(例如将内存中的数据写入到硬盘中)
IO 流又可分为 字节流 和 字符流
IO 流中的关系 - 图片来源菜鸟教程
字节流
字节流主要包括 FileInputStream 和 FileOutputStream
FileInputStream
下面演示 FileInputStream
package java0713.ioDemo;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* 演示字节流
* @author Administrator
*
*/
public class FileInputStreamDemo {public static void main(String[] args) {File file = new File("e:\\2.txt");
// 连接文件源建立输入流
// 这条语句也可用 InputStream is = new FileInputStream("FileAddress_StringPath")代替
try(InputStream is = new FileInputStream(file);) {byte[] buffer = new byte[4096];
int len = 0;
StringBuilder sb = new StringBuilder();
// // 错误示范,慎重使用 available
// int size = is.available();
// for (int i = 0; i < size; i++) {// System.out.print((char)is.read());
// }
do {// InputStream 字节流公有方法 read()
// 读取 buffer 个单位字节数据,返回单个流可读取最大长度,返回下一字节数据,结尾返回 -1,对 buffer 数组赋值
len = is.read(buffer);
if(len>0) {
// 为防止多出来的字节数组空间因未赋值而在转成字符串时变成空格,所以要限制它的长度为有效长度 len,当 len 为 - 1 时会报异常
sb.append(new String(buffer,0,len));
} else {break;}
} while(true);
// // 错误示范代码,条件写里面会报错
// do {// len = is.read(buffer);
// sb.append(new String(buffer,0,len));
// } while(len>0);
System.out.println(sb);
} catch (FileNotFoundException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
}
}
}
在这里 is 流从源 file 指向 buffer(buffer 再流向至 sb)
FileOutputStream
FileOutputStream 与 FileInputStream 用法类似,但是用数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,因为还有一部分有可能会留在内存这个缓冲区中。这时候如果你调用了 close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先 flush(),先清空数据。
package java0713.ioDemo;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* 演示输出流
* @author Administrator
*
*/
public class FileOutputStreamDemo {public static void main(String[] args) {
// 输出流连接目的地 target
try(OutputStream os = new FileOutputStream("e:\\3.txt");) {for (int i = 0; i < 255; i++) {os.write((char)i);
os.write('\r');
os.write('\n');
}
// flush 方法,刷新缓冲区,强制写入
os.flush();} catch (FileNotFoundException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
}
System.out.println("FileOutputSteam writes file successfully!");
}
}
其它流则有对象流(如输入输出集合框架对象)和二进制流(如输入输出基础数据类型)
内存流可以用于在流中的类型转换
字符流
字符流包括 InputStreamReader 和 OutputStreamWriter
字节流一次 read 返回一个字节,而字符流正如名字所示,一次 read 返回一个字符,所以字符流非常擅长输入输出有中文文本的流,而且用字符流输入输出对选择用何种方式的编码也非常方便
package java0713.ioDemo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 演示字符流 Reader/Writer
* @author Administrator
*
*/
public class InputStreamReaderDemo {public static void main(String[] args) {try(InputStream fis = new FileInputStream("e:\\2.txt");) {InputStreamReader reader = new InputStreamReader(fis,"gbk");
StringBuilder sb = new StringBuilder();
while(reader.ready()) {// 字符流一次 read()读取一个字符即两个字节
sb.append((char)reader.read());
}
System.out.println(sb);
} catch (FileNotFoundException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
}
}
}
OutputStreamWriter 方法与输入流类似,不再赘述