黑马程序员————IO流——字节流


------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

IO流——字节流


一.IO流:


 1、IO流的类的层次结构


  

A:字节流: 
   OutputStream:
      |--FileOutputStream:
      |--FilterOutputStream:(没学)
          |--BufferedOutputStream:(带缓冲区字节流)
   InputStream:
      |--FileInputStream:
      |--FilterInputStream:(没学)
         |--BufferedInputStream(带缓冲区字节流)
B:字符流:
   Writer:
     |--OutputStreamWriter(转换流)
        |--FileWriter:
     |--BufferedWriter(带缓冲区字符流)
   Reader:
     |--InputStreamReader(转换流)
        |--FileReader:
     |--BufferedReader:(带缓冲区的字符流)


 2.IO流概念:


  1).IO流:InputStream和OutputStream
  2).流:是有方向的,线性的;针对某个文件的输入输出流
     站在程序的角度:
          InputStream :从外部向程序中读入数据的
          OutputStream:从程序向外部输出数据
  3).分类:
      A.按流向:
            输出流
            输入流
      B.按读写方式:
            字节流:
            字符流:

二、FileOutputStream(类,继承自OutputStream抽象类)(文件可以不存在)
 

1.构造方法:

  覆盖写:
        FileOutputStream(String name):使用一个文件名构造一个输出流
        例子:FileOutputStream file=new FileOutputStream("D:\\aaa\\output.txt");
        FileOutputStream(File file);使用一个文件类型的引用构造一个输出流
        例子:FileOutputStream file=new FileOutputStream(new File("output.txt"));
   
   对于上述的例子中的文件既可以是绝对路径也可以是相对路径,相对路径就会在当前工作目录创建文件。
   这里会有一场出现,会在不能创建文件(磁盘问题,权限问题等)时出现异常,使用try...catch语句抛出异常即可

  追加写:
         FileOutputStream(String name,boolean append):
         FileOutputStream(File file,boolean append);追加写入,当判断为真时,在文件的末位。

 
 2.写入方法:


  A:public void write(int byte):向文件中写入一个字节。因此byte必须在字节的范围之内,即-128~127.但是负值有可能没有对应值。
  B:public viod write(byte[] byteArray):写入一个字节数组。
   ★★★如何把一个字符串转化为一个字节数组呢?使用String类的getBytes()方法获取字节数组byte[]
  C:public void write(byte[] byteArray,int off,int len):只写数组的一部分

 3.关闭流:


  close();关闭通道,结余资源,不然一直占用其他文件无法访问。


 4.输出换行符


  out.write("\r\n".getBytes());


★★5.加入异常处理


  1).直接在方法声明上抛出异常(不推荐)
  2).try..catch单组捕获异常
  3).try..catch 多组组合捕获异常


public class Demo {
   public static void main(String[] args) {
  	FileOutputStream out = null;
  	try {
    	     out = new FileOutputStream("output2.txt",true);//可能产生异常
   	     //写入数据
  	     out.write("你好Java".getBytes());//可能产生异常
  	     out.write("\r\n".getBytes());//可能产生异常
   
  	} catch (FileNotFoundException e) {
   	     System.out.println("无法创建系统文件,请查看您是否有权限访问磁盘,或查看磁盘空间是否够用!");
  	} catch (IOException e) {
   	     System.out.println("无法写入系统文件,请联系系统管理员!");
  	}finally{
  	 //释放资源
   	try {
   	     if(out != null){
    	 	out.close();
   	     }
  	 } catch (IOException e) {
    		System.out.println("无法关闭系统文件,请联系系统管理员!");
   	 }
 	}
  
    }
} 


  


三、FileInputStream(类,继承自InputStream)(文件必须存在,抛出异常:java.io.FileNotFoundException)


  1.构造方法:


         FileInputStream(String name):使用文件名创建一个输入流
         FileInputStream(File file):使用一个文件类型的引用创建一个输入流


  2.读取的方法:


   public int read();一次读取一个字节,返回一个Int值,可以打印,可以用char强转,但是可能没有意义。
   当读取到文件的末位时,会返回-1。可以读取换行符。在eclipse里面会显示是\r\n,是两个换行符。
   两种常用的循环遍历的方法:


    

方法一:
    int m=in.read();
    while(m!=-1){
        System.out.println(m+""+char(m));}
        m=in.read();
    方法二:
    int m=0;
    while((m=in.read())!=-1){
        System.out.println(m+""+char(m));}
  


  3.复制一个文本文件案例(用来做加密文字比较好啊)


   思路分析:
          1).从源文件读取数据,使用输入流
          2).一次读取一个字节
         3).向目标文件写入输出一个字节
             代码实现:

public class Demo {
   public static void main(String[] args)  {
 	 try {
   	     //创建一个输入流对象
   	     FileInputStream in=new FileInputStream("D:\\day20-copy.text");
   	     //创建一个输出流对象
   	     FileOutputStream out=new FileOutputStream("D:\\day20-copy1.java");
   	     //读取一个字节
   	     int n=0;
   	     while((n=in.read())!=-1){
   		 System.out.println(n+""+(char)n);
    		 out.write(n);
    
    	     }
   	     in.close();
             out.close();
  	    } catch (FileNotFoundException e) {
  		 System.out.println("捕获输入输出异常");
   		 e.printStackTrace();
  	    } catch (IOException e) {
  		 System.out.println("捕获读取写入异常");
   		 e.printStackTrace();
 	    }
  	   System.out.println("程序执行完毕!!!");
 	}
}   



   
   4.第二种读取方法:public int read(byte[] byteArray):


   ★★★如何打印字节数组的内容呢?
   很简单的,Array.toString(byteArray),其打印结果是,用[]括起来的,用逗号分隔的数组元素的字符串。

   ★★★使用String的构造方法,可以将一个byte数组转换为一个字符串。
   String(byte[] bytes)
   String(byte[] bytes, int offset, int length)
   读取到文本底部时,返回值也是-1.
   
   基本使用方法:

   //创建一个字符数组
   byte[] byteArray=new byte[20];一般根据需要定义数组的长度
   int n=0;
   while((n=in.read(byteArray))!=-1){
    String s=new String(byteArray,0,n);//此种的构造方法,可以恰到好处的取出全部的内容★★
    ★★//实际上n代表的就是数组中被再次填入的元素个数,最后一次填入,可能填不满,但是原来的元素不会被全部覆盖。
    System.out.println(s);
   }


   一次读取一个字节数组,复制文本文件。视频同样方法。代码实现:

public class Demo {
 public static void main(String[] args) throws IOException {
  //1.文件的输入流:文件必须存在,否则抛出异常
  FileInputStream in = new FileInputStream("D:\\aaa\\StringDemo.java");
  //2.文件的输出流:文件可以不存在。如果不存在,则创建
  FileOutputStream out = new FileOutputStream("StringDemo_demo02_copy.java");
  
  //开始复制:
  //一次读取一个字节数组
  byte[] byteArray = new byte[1024];
  int n = 0;
  while((n = in.read(byteArray)) != -1){
   //写入,一次写入一个byte数组
   out.write(byteArray, 0, n);
  }
  //释放资源
  in.close();
  out.close();
  System.out.println("复制完毕!下课");
 }
}


四、带缓冲的字节流


  1.缓冲的字节流概述

   可以看到使用字节数组可以大大加快复制速度,由于数组具有缓冲区功能。一次读取的数据填充到数组中,然后再一次写入,提高了效率。
  
  2.带缓冲的字节流


   BufferedInputStream;带缓冲的输入流
   BufferedOutputStream;带缓冲的输出流

  3.带缓冲的输出流:BufferedOutputStream


   BufferedOutputStream:带缓冲的输出流:只要是OutputStream的子类都可以,我们学过:FileOutputStream;
   BufferedOutputStream只提供了"缓冲区",只是写进了内存去,内部写入,仍然使用参数传递的FileOutputStream对象实现。
   
   BufferedOutputStream(OutputStream out) :创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
   BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。

   输出流的写入的方法:它没有特有的写入方法,使用父类的即可
   注意:如果要实现追加写的话,就要在构建OutputStream时准备好。
      flush(),刷新缓冲区,实现写入功能。
      close(),内部集成了刷新功能,可以不用再刷新了。


  
  4.带缓冲的输入流:BufferedInputStream


   BufferedInputStream(InputStream in) : 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
   BufferedInputStream(InputStream in, int size) : 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
  
   没有特有方法,使用父类的方法
    int read():读取一个字节
    int read(byte[] byteArray):读取一个字节数组


  5.五种方式复制文件速度对比


   1.一次读、写一个字节:使用基本流:FileInputStream 和 FileOutputStream -- > method1():  57626毫秒
   2.一次读、写一个字节数组:使用基本流:FileInputStream 和 FileOutputStream --> method2();  149 毫秒

   3.一次读、写一个字节:缓冲流:BufferdInputStream 和 BufferedOutputStream --> method3(); 958 毫秒
   4.一次读、写一个字节数组:缓冲流:BufferdInputStream 和 BufferedOutputStream --> method4(); 66 毫秒
 
   结论:读写"二进制"文件,首选带缓冲的字节流。

//1.一次读、写一个字节:使用基本流:FileInputStream 和 FileOutputStream -- > method1()
 private static void method1() throws IOException{
  FileInputStream in = new FileInputStream("D:\\aaa\\哥有老婆.mp4");
  FileOutputStream out = new FileOutputStream("哥有老婆_copy1.mp4");
  
  //开始复制,一次读写一个字节
  int n = 0;
  while((n = in.read()) != -1){
   out.write(n);//写入一个字节
  }
  //释放资源
  in.close();
  out.close();
  
 }




 //2.一次读、写一个字节数组:使用基本流:FileInputStream 和 FileOutputStream --> method2();
 private static void method2() throws IOException{
  FileInputStream in = new FileInputStream("D:\\aaa\\哥有老婆.mp4");
  FileOutputStream out = new FileOutputStream("哥有老婆_copy2.mp4");
  
  //开始复制,一次读写一个字节数组
  byte[] byteArray = new byte[1024];
  int n = 0;
  while((n = in.read(byteArray)) != -1){
   out.write(byteArray,0,n);//一次写入一个字节数组
  // out.flush();
  }
  //释放资源
  in.close();
  out.close();
 }





 //3.一次读、写一个字节:缓冲流:BufferdInputStream 和 BufferedOutputStream --> method3()
 private static void method3() throws IOException{
  BufferedInputStream in = new BufferedInputStream(new FileInputStream("D:\\aaa\\哥有老婆.mp4"));
  BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("哥有老婆_copy3.mp4"));
  
  //一次读、写一个字节
  int n = 0;
  while((n = in.read()) != -1){
   out.write(n);
  }
  //释放资源
  in.close();
  out.close();
 }




 //4.一次读、写一个字节数组:缓冲流:BufferdInputStream 和 BufferedOutputStream --> method4();
 private static void method4() throws IOException {
  BufferedInputStream in = new BufferedInputStream(new FileInputStream("D:\\aaa\\哥有老婆.mp4"));
  BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("哥有老婆_copy3.mp4"));
  
  //一次读、写一个字节数组
  byte[] byteArray = new byte[1024];
  int n = 0;
  while((n = in.read(byteArray)) != -1){
   out.write(byteArray,0,n);
  }
  //释放资源
  in.close();
  out.close();
 }


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值