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



------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

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();
 }


你可能感兴趣的:(IO流,字节流,缓冲字节流)