文章目录 [隐藏]
FileInputStream、BufferedInputStream的基类为输入字节流的抽象类InputStream,子类必须总是提供返回下一个输入字节的方法;
FileOutputStream、BufferedOutputStream的基类为输出字节流的抽象类OutputStream,子类必须始终提供至少一种可写入一个输出字节的方法。
一。使用FileOutputStream创建文件,使用FileInputStream读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
public static void main(String[] args) { // 一。使用字节文件输出流创建一个文件 FileOutputStream fos = null; try { // 1.字节文件输出流 fos = new FileOutputStream("stream.txt"); fos.write("ss\r\ndffffg".getBytes());// 2.无需刷新,对字节直接操作 } catch (IOException e) { e.printStackTrace(); } finally { try { fos.close();// 3.关闭资源 } catch (IOException e) { e.printStackTrace(); } } // 二。使用字节文件输入流读取文件 System.out.println("-- 每次读一个字节 --------------------------------------"); FileInputStream fis = null; try { // 1.字节输入流 fis = new FileInputStream("stream.txt"); int ch = 0; // 2.读单个字节 while ( (ch = fis.read()) != -1) { System.out.print("字节:" + (char)ch); } } catch (IOException e) { e.printStackTrace(); } finally { try { // 3.关闭流 fis.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("\n-- 每次读一个数组长度字节 --------------------------------------"); try { fis = new FileInputStream("stream.txt"); byte[] buf = new byte[1024]; // 缓存 int len = 0; // 缓存量 while ((len = fis.read(buf)) != -1) { // 循环读取数据,直到完毕 System.out.print("数组:" + new String(buf, 0, len)); } } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } System.out.println("\n-- available获取文件长度 --------------------------------------"); try { fis = new FileInputStream("stream.txt"); int available = fis.available(); // 包括\r \n在内的全部字节数量 byte[] buf = new byte[available]; // JVM默认4M内存,电脑物理内存4G、8G、16G、...,如果文件有32G大于可用内存,则发生溢出 fis.read(buf); // 所以谨慎使用此方法 System.out.println(new String(buf)); } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } |
二。使用FileOutputStream和FileInputStream复制文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
/** * 非字符文件读写复制。字节复制 * 图片、mp3文件、exe程序文件、视频文件 * * 不能使用字符流类复制图片等文件,因为 * 字符流类会对数据进行转码 */ public static void main(String[] args) { FileInputStream fis = null; FileOutputStream fos = null; try { // 1.字节流对象 fis = new FileInputStream("test.exe"); // 输入流 fos = new FileOutputStream("test2.exe"); // 输出流 byte[] buf = new byte[1024]; // 缓存字节数组 int len = 0; // 缓存长度 // 2.读取字节到缓存,并判断长度。读取结束时长度为-1,结束 while ( (len = fis.read(buf)) != -1) { // 3.将缓存字节数据 写到流,有多少写多少 fos.write(buf, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (fis != null ) // 4.关闭流 fis.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null){ try { fos.close();// 关闭流 } catch (IOException e) { e.printStackTrace(); } } } } } |
三。使用带有缓冲区的BufferedOutputStream和BufferedInputStream复制文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public static void main(String[] args) throws Exception { long startTime = System.currentTimeMillis(); // 首先读写字节流,到缓冲区对象 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.exe")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test3.exe")); /* -- 每次读写一字节 int byter = 0; while((byter = bis.read())!=-1){ bos.write(byter); } */ // -- 每次读写一个数组单位的字节 byte[] buff = new byte[1024]; int len = 0; // 然后从缓冲区对象(的缓存)提取数据到缓存数组,进行读写 while((len = bis.read(buff)) != -1){ bos.write(buff, 0, len); } // 最后关闭流 bos.close(); bis.close(); long endTime = System.currentTimeMillis(); System.out.println("耗时:" + (endTime - startTime) + "毫秒"); } |
四。模拟有缓冲区功能的InputStream字节输入流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
public class MyBufferedInputStreamTest { public static void main(String[] aregs) throws IOException{ // 模拟创建的缓冲区字节输入流对象 MyBufferedInputStream mbis = new MyBufferedInputStream(new FileInputStream("test.exe")); // 字节输出流 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("test2.exe")); int b = 0; // 自定义字节输入流对象读取的字节 // 1.不断的从缓冲区返回单个字节 while ((b = mbis.myRead()) != -1){ // 2.字节输出流写文件时,进行int->byte强转 bos.write(b); } bos.close(); mbis.myClose(); } } /** * 自定义字节输入流 * @author cuiweiyou.com */ class MyBufferedInputStream { private InputStream is; // 被装饰的类 private byte[] buf = new byte[1024]; // 缓冲区 private int len = 0; // 每次缓冲的字节数量 private int pos = 0; // 缓冲的字节读取到的位置 public MyBufferedInputStream(InputStream is) { this.is = is; } public int myRead() throws IOException { // 1. 如果缓冲区中字节数为0,说明缓冲区中读取完毕,空 if (len == 0){ len = is.read(buf); // 1> 填满缓冲区 if (len < 0){ // 此时为-1,说明读文件完毕 return -1; } pos = 0; // 2> 每重新填满缓冲区,即从0索引开始读取 byte b = buf[pos]; // 3> 返回缓冲区第一个字节 len --; // 4> 更新缓冲区有效元素长度 pos ++; // 5> 更新下次读取的位置 /* byte提升为int,从8位提升到32位。 * 与255后,仅保留最低8位原有效数据,其余24位补0。 * 避免读到连续8个1时返回-1的情况。 * 尽管返回了4倍的字节数量,但OutputStream的write写时进行了int->byte的强转,仅写最低8位 */ return b & 255; // 6> 返回一个字节 } // 2. 如果缓冲区里还有数据,接着读取 else if (len > 0){ byte b = buf[pos]; // 7> 在新的位置读取缓冲区 len --; // 8> 更新剩余元素长度 pos ++; // 9> 更新下次读取位置 return b & 255; // 10> 返回数据 } return -1; } public void myClose() throws IOException{ is.close(); } } |
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/1043.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设