- 基本读取操作:
- InputStream();
- OutputStream(); // 直接写入目的地中, 不需要 flush() 刷新
- write(byte[] b); // 参数为 byte 数组
- 字符流不能操作媒体文件, 因为字符流读入文件后, 需要对照编码表. 如果编码表中没有对应的数据, 这时, 码表会用一些未知字符区的编码替代,最终,会发生错误.
// 示例一: 写入数据 // 1. 创建字节输出流对象, 用于操作文件 FileOutputStream fos = new FileOutputStream("demo.js"); //2. 写入数据, 注意写入的为 byte 类型, 并且直接写入到目的地中, 不需要 flush() fos.write("abc".getBytes()); //3, 关闭资源 fos.close();// 示例二: 读取数据 // 1, 创建读取流对象, 和指定文件关联 FileInputStream fis = new FileInputStream("demo.js"); // 2. 读取字节数组 byte[] buf = new byte[1024]; int len = 0; while((ch=fis.read(buf)) != -1){ System.out.println(new String(buf,0,len)); } /* * // 一次读取一个字节 * int ch = 0; * while((ch=fis.read()) != -1){ * System.out.println((char)ch); * } */ // 3. 关闭流 fis.close(); // 备注: fis.available(); 可以获取文件大小// 示例三: 复制一个 mp3 媒体文件 public static void copyMp3() throws IOException { FileInputStream fis = new FileInputStream("demo.mp3"); BufferedInputStream bufis = new BufferedInputStream(fis); FileOutputStream fos = new FileOutputStream("my.mp3"); BufferedOutputStream bufos = new BufferedOutputStream(fos); /* * byte[] buf = new byte[1024]; * * int len = 0; * while((len=bufis.read(buf))!=-1){ * bufos.write(buf,0,len); * bufos.flush(); // 使用缓冲区的读, 每次读完后, 需要刷新 * } */ // 缓冲区读取单个字符 int ch = 0; while((ch=bufis.read())!=-1){ bufos.write(ch); } bufos.close(); bufis.close(); }// 示例四: 读取一个键盘录入的数据, 并将数据变成大写显示在控制台上, // 如果用户输入的是 over, 结束键盘录入 /* 分析: * 键盘本身就是一个标准的输入设备, * 对于 java 而言, 对于这种输入设备都有对应的对象. * 键盘录入对应的对象位于 java.lang 包中的 System 类 * "in" : 标准输入 * "out" : 标准输出 * 思路: * 1. 因为键盘录入只读取一个字节, 要判断是否是 over, 需要将读取到的字节拼成字符串 * 2. 那就需要一个容器, StringBuilder * 3. 在用户回车之前, 将录入的数据变成字符串判断即可 * * 步骤: * 1. 创建容器 * 2. 获取键盘读取流 * 3. 定义变量记录读取到的字节, 并循环获取 * 4. 将读取到的字节存储到 StringBuilder 中 * 5. 在存储之前需要判断是否是换行标记, 因为换行标记不存储 */ public static void readKey() throws IOException{ // 1. 创建容器 StringBulider sb = new StringBuilder(); // 2. 获取键盘读取流 InputStream in = System.in; // 3. 定义变量记录读取到的字节, 并循环获取 int ch = 0; while((ch=in.read())!=-1){ // 在存储之前需要判断是否是换行标记, 因为换行标记不存储 if(ch=='\r') continue; if(ch=='\n'){ String temp = sb.toString(); if("over".equals(temp)) break; System.out.println(temp.toUpperCase()); sb.delete(0,sb.length()); // 每次输出后,需要清空 StringBuilder 容器. // 集合的清空用 clear } else{ sb.append((char)ch); // 需要变成字符存储进容器 } } }
转换流
- 将字节流转换为字符流的桥梁:
InputStreamReader();
相当于解码 - 将字符流转换为字节流的桥梁:
OutputStreamWriter();
相当于编码 - 转换过程中,可以指定编码表
// 示例四: 读取一个键盘录入的数据, 并将数据变成大写显示在控制台上, // 如果用户输入的是 over, 结束键盘录入 public static void readKey() throws IOException{ // 字节流 InputStream in = System.in; // 将字节流转换为字符流 InputStreamReader isr = new InputStreamReader(in); // 缓冲区修饰字符流 BufferedReader bufr = new BufferedReader(isr); // 获取输出流 OutputStream out = System.out; // 将字符流转换为字节流, 构造函数可以接收 字节流 OutputStreamWriter osw = new OutputStreamWriter(out); BufferedWriter bufw = new BufferedWriter(osw); String line = null; while((line=bufr.readLine())!=null){ if("over".equals(line)) break; // System.out.println(line.toUpperCase()); // 每次读取到的 line 是字符, 将字符写入到字节输入流中, 需要用到 OutputStreamWriter bufw.write(line.toUpperCase()); bufw.newLine(); // 换行 bufw.flush(); // 每次写入后,需要刷新. 将流中的数据刷到控制台上 } } // 升级版本: BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
参考资料