IO流(2):字节流及其缓冲流
IO流(二):字节流及其缓冲流


2、中文的处理
一、IO概述
1、分类
1) 流向:
- 输入流 读取数据
- 输出流 写出数据
2) 数据类型:
-
字节流
- 字节输入流 读取数据 InputStream
- 字节输出流 写出数据 OutputStream
-
字符流
- 字符输入流 读取数据 Reader
- 字符输出流 写出数据 Writer
-
注意:
- 一般我们在探讨IO流的时候,如果没有明确说明按哪种分类来说,默认情况下是按照数据类型来分的。
-
每种基类的子类都是以父类名作为后缀名。
- XxxOutputStream
- XxxInputStream
- XxxReader
- XxxWriter
二、FileOutputStream:文件输出流
(一)概述
1、特点
1)文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。
2)文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。
3)FileOutputStream 用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用 FileWriter 。
2、构造方法
1)不追加:
- FileOutputStream(File file)
- FileOutputStream(String name)
2)可追加
- FileOutputStream(File file, boolean append)
- FileOutputStream(String name, boolean append)
(二)功能
1、输出功能
1)public void write(int b):写一个字节
-
换行:
- windows:\r\n
- linux:\n
- Mac:\r
-
write(97)
- 97 : 底层二进制数据
- 通过记事本打开 ,找97对应的字符值 :a
2)public void write(byte[] b):写一个字节数组
- getBytes():转换为字节数据
<span style="font-family:Arial;font-size:18px;"> //写数据 fos.write("hello,IO".getBytes()); fos.write("java".getBytes());</span>
3)public void write(byte[] b,int off,int len):写一个字节数组的一部分
<span style="font-family:Arial;font-size:18px;"> /* * 字节输出流操作步骤: * A:创建字节输出流对象 * B:调用write()方法 * C:释放资源 * * public void write(int b):写一个字节 * public void write(byte[] b):写一个字节数组 * public void write(byte[] b,int off,int len):写一个字节数组的一部分 */ public void test2() throws IOException{ // 创建字节输出流对象 // OutputStream os = new FileOutputStream("fos2.txt"); // 多态 FileOutputStream fos = new FileOutputStream("fos.txt"); // 调用write()方法 fos.write(97); //97 -- 底层二进制数据 -- 通过记事本打开 -- 找97对应的字符值 -- a // fos.write(57); // fos.write(55); //public void write(byte[] b):写一个字节数组 byte[] bys={97,98,99,100,101}; fos.write(bys); //public void write(byte[] b,int off,int len):写一个字节数组的一部分 fos.write(bys,1,3); //释放资源 fos.close(); }</span>
三、FileInputStream:文件输入流
(一)概述
1、特点
1)FileInputStream 从文件系统中的某个文件中获得输入字节。
2)哪些文件可用取决于主机环境。
3)FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。
2、构造方法
1)FileInputStream(File file)
2)FileInputStream(String name)
(二)功能
1、读取功能
1) int read():一次读取一个字节
- 获取的是字节码,需要转换成字符。
- 如果读取的数据是-1,说明已经读取到文件的末尾。
int by = 0; // 读取,赋值,判断 while ((by = fis.read()) != -1) { System.out.print((char) by); } // 释放资源 fis.close();
2)int read(byte[] b):一次读取一个字节数组
- 字符数组与字节数组都可以直接转换成 String。
- 定义的字符数组的长度一般是1024或者1024的整数倍。
// 数组的长度一般是1024或者1024的整数倍 byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { // System.out.println(len); System.out.print(new String(bys, 0, len)); } // 释放资源 fis.close();
(三)实例
1、拷贝文件数据(文本、图片、音乐)
1)单个字节
2)字节数组
<span style="font-family:Arial;font-size:18px;"> /* * 需求:把e:\\林青霞.jpg内容复制到当前项目目录下的mn.jpg中 * * 数据源: * e:\\林青霞.jpg --读取数据--FileInputStream * 目的地: * mn.jpg--写出数据--FileOutputStream */ public void test4() throws IOException{ // 封装数据源 FileInputStream fis = new FileInputStream("e:\\林青霞.jpg"); // 封装目的地 FileOutputStream fos = new FileOutputStream("mn.jpg"); // 复制数据 int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } // 释放资源 fos.close(); fis.close(); //字节数据,图片、音乐等都可以处理 /* // 封装数据源 FileInputStream fis = new FileInputStream("e:\\哥有老婆.mp4"); // 封装目的地 FileOutputStream fos = new FileOutputStream("copy.mp4"); // 复制数据 int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } // 释放资源 fos.close(); fis.close();*/ //利用字节数组处理 // 封装数据源 FileInputStream fiss = new FileInputStream("e:\\哥有老婆.mp4"); // 封装目的地 FileOutputStream foss = new FileOutputStream("copy.mp4"); // 复制数据 byte[] bys = new byte[1024]; int len = 0; while ((len = fiss.read(bys)) != -1) { foss.write(bys, 0, len); } // 释放资源 fos.close(); fis.close(); }</span>
2、中文的处理
/* * 计算机是如何识别什么时候该把两个字节转换为一个中文呢? * 在计算机中中文的存储分两个字节: * 第一个字节肯定是负数。 * 第二个字节常见的是负数,可能有正数。但是没影响。 */ public void test5() { // String s = "abcde"; // // [97, 98, 99, 100, 101] String s = "我爱你中国"; // [-50, -46, -80, -82, -60, -29, -42, -48, -71, -6] byte[] bys = s.getBytes(); System.out.println(Arrays.toString(bys)); }
四、BufferedOutputStream、BufferedInputStream 缓冲流
(一)概述
1、BufferedOutputStream 类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
2、BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。
- 在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。
- mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。
(二)功能:高效字节流一次读写一个字节数组
1、比较各个读取方式的效率/* * 需求:把e:\\哥有老婆.mp4复制到当前项目目录下的copy.mp4中 * * 字节流四种方式复制文件: * 基本字节流一次读写一个字节: 共耗时:117235毫秒 * 基本字节流一次读写一个字节数组: 共耗时:156毫秒 * 高效字节流一次读写一个字节: 共耗时:1141毫秒 * 高效字节流一次读写一个字节数组: 共耗时:47毫秒 */ public void test3() throws IOException { long start = System.currentTimeMillis(); // method1("e:\\哥有老婆.mp4", "copy1.mp4"); // method2("e:\\哥有老婆.mp4", "copy2.mp4"); // method3("e:\\哥有老婆.mp4", "copy3.mp4"); method4("e:\\哥有老婆.mp4", "copy4.mp4"); long end = System.currentTimeMillis(); System.out.println("共耗时:" + (end - start) + "毫秒"); } // 高效字节流一次读写一个字节数组: public static void method4(String srcString, String destString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcString)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destString)); byte[] bys = new byte[1024]; int len = 0; while ((len = bis.read(bys)) != -1) { bos.write(bys, 0, len); } bos.close(); bis.close(); } // 高效字节流一次读写一个字节: public static void method3(String srcString, String destString) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream( srcString)); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(destString)); int by = 0; while ((by = bis.read()) != -1) { bos.write(by); } bos.close(); bis.close(); } // 基本字节流一次读写一个字节数组 public static void method2(String srcString, String destString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(destString); byte[] bys = new byte[1024]; int len = 0; while ((len = fis.read(bys)) != -1) { fos.write(bys, 0, len); } fos.close(); fis.close(); } // 基本字节流一次读写一个字节 public static void method1(String srcString, String destString) throws IOException { FileInputStream fis = new FileInputStream(srcString); FileOutputStream fos = new FileOutputStream(destString); int by = 0; while ((by = fis.read()) != -1) { fos.write(by); } fos.close(); fis.close(); }