Day26

今天从11点半开始学习到下午四点,专注学习时间大于三个小时了,今晚大概率不去图书馆了,所以下午先把今天的博客敲出来先。IO流学习过程还是比较简单的。Day26了,加油OVO

Day26

duplicated code fragment,代码重复出现的意思。

缓冲流

package com.sorrymaker.IO;

import org.junit.Test;

import java.io.*;

/**
* 缓冲流的作用:提升流的读取,写入的速度。
*/
public class BufferedTest {

   /**
   实现非文本文件的复制。
    */
   @Test
   public void BufferedStreamTest() {
       FileInputStream fis = null;
       FileOutputStream fos = null;
       BufferedInputStream bis = null;
       BufferedOutputStream bos = null;
       try {
           //1.造文件
           File file1 =new File("src/com/sorrymaker/IO/01.png");
           File file2 =new File("src/com/sorrymaker/IO/03.png");
           //2.1造流
           fis = new FileInputStream(file1);
           fos = new FileOutputStream(file2);
           //2.2 造缓冲流
           bis = new BufferedInputStream(fis);
           bos = new BufferedOutputStream(fos);
           //3.传数据
           byte[] buffer =new byte[10];
           int len;
           //这里拿bis.read()
           while ((len = bis.read(buffer)) != -1) {
               //这里用bos
               bos.write(buffer,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           //4.关闭流资源,这里有关闭顺序的要求,先关闭外层,再关闭内层
           //关闭外层的同时,内层流也会自动的关闭,关于内层流的关闭,我们可以省略
           if(bis!=null){
               try {
                   bis.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if (bos!=null){
               try {
                   bos.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
   //实现文件复制的方法
   public void copyFileWithBuffered(String srcPath,String destPath){
       FileInputStream fis = null;
       FileOutputStream fos = null;
       BufferedInputStream bis = null;
       BufferedOutputStream bos = null;
       try {
           //1.造文件
           File srcFile =new File(srcPath);
           File destFile =new File(destPath);
           //2.1造流
           fis = new FileInputStream(srcFile);
           fos = new FileOutputStream(destFile);
           //2.2 造缓冲流
           bis = new BufferedInputStream(fis);
           bos = new BufferedOutputStream(fos);
           //3.传数据
           byte[] buffer =new byte[1024];
           int len;
           //这里拿bis.read()
           while ((len = bis.read(buffer)) != -1) {
               //这里用bos
               bos.write(buffer,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           //4.关闭流资源,这里有关闭顺序的要求,先关闭外层,再关闭内层
           //关闭外层的同时,内层流也会自动的关闭,关于内层流的关闭,我们可以省略
           if(bis!=null){
               try {
                   bis.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if (bos!=null){
               try {
                   bos.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
   @Test
   public void testCopyFileWithBuffered(){
       String srcPath="D:\\Desktop\\python.pdf";
       String destPath="D:\\Desktop\\001.pdf";
       long start = System.currentTimeMillis();
       copyFileWithBuffered(srcPath,destPath);
       long end = System.currentTimeMillis();
       System.out.println("复制成功,花费时间为"+(end-start)+"s");

  }
}

练习

1.FileInputSteam/FileOutputStream/BufferedInputStream/BufferedOutputStreams实现复制操作。比较两者的效率.

package com.sorrymaker;

import org.junit.Test;

import java.io.*;

public class Day26Test {
   /**
    * 1.使用FileInputSteam/FileOutputStream/BufferedInputStream/BufferedOutputStreams实现复制操作
    *   比较两者的效率.
    */
   @Test
   public void copyTest(){
       String srcPath ="D:\\Desktop\\python.pdf";
       String destPath1 ="D:\\Desktop\\002.pdf";
       String destPath2 ="D:\\Desktop\\003.pdf";
       long start = System.currentTimeMillis();
       fileCopyTest(srcPath,destPath1);
       long end = System.currentTimeMillis();
       System.out.println("不使用缓冲流的时间为:"+(end-start));
       long start1 = System.currentTimeMillis();
       bufferedCopyTest(srcPath,destPath2);
       long end1 = System.currentTimeMillis();
       System.out.println("使用缓冲区后的时间为"+(end1-start1));
  }
   public void fileCopyTest(String srcPath,String destPath1){
       FileInputStream fis = null;
       FileOutputStream fos = null;
       try {
           File srcFile =new File(srcPath);
           File destFile =new File(destPath1);

           fis = new FileInputStream(srcFile);
           fos = new FileOutputStream(destFile);

           byte[] buffer =new byte[10];
           int len;
           while ((len = fis.read(buffer)) != -1) {
               fos.write(buffer,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if(fis!=null){
               try {
                   fis.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if(fos!=null){
               try {
                   fos.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
   public void bufferedCopyTest(String scrPath,String destPath2){
       BufferedInputStream bis = null;
       BufferedOutputStream bos = null;
       try {
           File srcFile =new File(scrPath);
           File destFile =new File(destPath2);

           FileInputStream fis= new FileInputStream(srcFile);
           FileOutputStream fos = new FileOutputStream(destFile);

           bis = new BufferedInputStream(fis);
           bos = new BufferedOutputStream(fos);

           byte[] buffer =new byte[10];
           int len;
           while ((len = bis.read(buffer)) != -1) {
               bos.write(buffer,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if(bis!=null){
               try {
                   bis.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if(bos!=null){
               try {
                   bos.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
}

2.实现图片加密和解密操作

重点m=12,n=5,m^n^n=m, 先^一次,就加密,再^一次,就解密了.

    /**
    * 实现图片加密操作
    */
   @Test
   public void test2() {
       FileInputStream fis = null;
       FileOutputStream fos  = null;
       try {
           fis = new FileInputStream("src/com/sorrymaker/IO/01.png");
           fos = new FileOutputStream("src/com/sorrymaker/IO/secret01.png");
           byte[] buffer =new byte[20];
           int len;
           while ((len = fis.read(buffer)) != -1) {
               //对字节数据进行修改.
               for (int i = 0; i < len; i++) {
                   buffer[i] =(byte) (buffer[i]^5);
              }
               fos.write(buffer,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if(fos!=null){
               try {
                   fos.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if(fis!=null){
               try {
                   fis.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
   /**
    * 图片解密
    */
   @Test
   public void  test22(){
       FileInputStream fis = null;
       FileOutputStream fos  = null;
       try {
           fis = new FileInputStream("src/com/sorrymaker/IO/secret01.png");
           fos = new FileOutputStream("src/com/sorrymaker/IO/04.png");
           byte[] buffer =new byte[20];
           int len;
           while ((len = fis.read(buffer)) != -1) {
               //对字节数据进行修改.
               for (int i = 0; i < len; i++) {
                   buffer[i] =(byte) (buffer[i]^5);
              }
               fos.write(buffer,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if(fos!=null){
               try {
                   fos.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if(fis!=null){
               try {
                   fis.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
}

3.获取文本上每个字符出现的次数.

提示:遍历文本的每一个字符;字符及出现的次数保存在Map中;将Map中的数据写入文件。

    /**
    * 3.获取文本上每个字符出现的次数.
    * 提示:遍历文本的每一个字符;字符及出现的次数保存在Map中;将Map中的数据写入文件。
    */
   @Test
   public void test3() {
       FileReader fr = null;
       BufferedWriter bw = null;
       try {
           //1.创建Map集合
           HashMap<Character, Integer> map = new HashMap<>();
           //2.遍历字符.
           fr = new FileReader("D:\\Desktop\\001.txt");
           int c;
           while ((c = fr.read()) != -1) {
               char ch =(char) c;
               //判断char是否在map中第一次出现.
               if(map.get(ch)==null){
                   map.put(ch,1);
              }else {
                   map.put(ch,map.get(ch)+1);
              }
          }
           //3.把map中数据存在002.txt中
           //3.1创建writer
           bw = new BufferedWriter(new FileWriter("D:\\Desktop\\002.txt"));

           //3.2遍历map,再写入数据
           Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
           for(Map.Entry<Character,Integer> entry : entrySet){
               switch (entry.getKey()){
                   case ' ':
                       bw.write("空格="+entry.getValue());
                       break;
                   case '\t':
                       bw.write("tab键="+entry.getValue());
                       break;
                   case '\r':
                       bw.write("回车="+entry.getValue());
                       break;
                   case '\n':
                       bw.write("换行="+entry.getValue());
                       break;
                   default:
                       bw.write(entry.getKey()+"="+entry.getValue());
                       break;
              }
               bw.newLine();
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if(bw!=null){
               try {
                   bw.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if(fr!=null){
               try {
                   fr.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }

 

 

转换流

package com.sorrymaker.IO;

import org.junit.Test;

import java.io.*;

/**
* 处理流中的转换流
* 1转换流(看后缀),属于字符流
*     InputStreamReader:将一个字节的输入流转为字符的输入流
*     OutputStreamWriter:将一个字符的输出流转换为字节的输出流
* 2.作用:提供字节流与字符流之间的转换.
*
* 3.解码:字节,字节数组 ---> 字符数组,字符串 --->InputStreamReader
*   编码:字符数组,字符串 ---> 字节,字节数组. --->OutputStreamWriter
*
* 4.字符集
* @author 喜
*/
public class InputStreamWriterTest {
   /**
    *   InputStreamReader(),实现字节的输入流到字符的输入流的转换.
    */
   @Test
   public void test1(){
       InputStreamReader isr1 = null;
       try {
           FileInputStream fis =new FileInputStream("src/com/sorrymaker/IO/hello1.txt");
//       InputStreamReader isr =new InputStreamReader(fis);//使用系统默认的字符集.
           //参数二指明了字符集,具体使用哪个字符集,取决于文件保存时使用的字符集
           isr1 = new InputStreamReader(fis);

           char[] cbuf =new char[20];
           int len;
           while ((len = isr1.read(cbuf)) != -1) {
               String str =new String(cbuf,0,len);
               System.out.println(str);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if(isr1!=null){
               try {
                   isr1.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
   /**
   综合使用InputStreamReader/OutputStreamWriter。
    */
   @Test
   public void test2(){

       InputStreamReader isr = null;
       OutputStreamWriter osw = null;
       try {
           File file1 =new File("src/com/sorrymaker/IO/hello1.txt");
           File file2 =new File("src/com/sorrymaker/IO/copyhello1.txt");

           FileInputStream fis =new FileInputStream(file1);
           FileOutputStream fos =new FileOutputStream(file2);

           isr = new InputStreamReader(fis);
           osw = new OutputStreamWriter(fos,"gbk");

           char[] cbuf =new char[20];
           int len;
           while ((len = isr.read(cbuf)) != -1) {
               osw.write(cbuf,0,len);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if(osw!=null){
               try {
                   osw.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
           if(isr !=null){
               try {
                   isr.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }
}

 

其他流

package com.sorrymaker.IO;

import org.junit.Test;

import java.io.*;

/**
* 其他流的使用
* 1.标准的输入、输出流
* 2.打印流
* 3.数据流
*/
public class OtherStreamTest {
   /**
    * 1.标准的输入、输出流
    * 1.1
    * System.in:标准的输入流,默认从键盘输入。
    * System.out:标准的输出流,默认从控制台输出。
    * 1.2
    * System类的setIn(InputStream is)和setOut(PrintStream ps)方式重新指定输入和输出的流
    * 1.3练习:
    * 从键盘输入字符串,要求将读到的整行字符串转成大写输出,然后继续进行输入操作,直至输入"e"或"exit"时,退出程序
    * <p>
    * 方法一:使用Scanner实现,调用next()获取用户的输入。
    * 方法二:使用System.in实现。System.in --->转换流 ---> BufferedReader的readLine()
    */
   public static void main(String[] args) {
       BufferedReader br = null;
       try {
           InputStreamReader isr = new InputStreamReader(System.in);
           br = new BufferedReader(isr);
           while (true) {
               System.out.println("请输入字符串:");
               String data = br.readLine();
               if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)) {
                   System.out.println("程序结束");
                   break;
              }
               String upperCase = data.toUpperCase();
               System.out.println(upperCase);
          }
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if (br != null) {
               try {
                   br.close();
              } catch (IOException e) {
                   e.printStackTrace();
              }
          }
      }
  }

   /**
    * 2.打印流:PrintStream 和PrintWriter
    * 2.1 提供了一系列重载的print()和println()
    * 2.2 练习
    */

   /**
    * 3.数据流
    * 3.1 DataInputStream 和 DataOutputStream
    * 3.2 作用:用于读取或写出基本数据类型的变量或字符串
    *
    * 练习:将内存中的字符串,基本数据类型的变量写出到文件中
    *
    */
   @Test
   public void test3() throws IOException {

       DataOutputStream dos =new DataOutputStream(new FileOutputStream("src/com/sorrymaker/IO/hello2.txt"));

       dos.writeUTF("啦啦啦");
       //刷新操作,将内存中的数据写入文件
       dos.flush();
       dos.writeInt(23);
       dos.flush();
       dos.writeBoolean(true);
       dos.flush();
       dos.close();

  }

   /**
    * 将文件中的基本数据类型变量和字符串读取到内存中,保存再变量中。
    *
    * 注意点!!!!:读取顺序要与写入顺序一致
    *
    * @throws IOException
    */
   @Test
   public void test4() throws IOException {
       DataInputStream dis =new DataInputStream(new FileInputStream("src/com/sorrymaker/IO/hello2.txt"));

       String name = dis.readUTF();
       int age = dis.readInt();
       boolean isMan = dis.readBoolean();

       System.out.println("name="+name);
       System.out.println("age="+age);
       System.out.println("isMan="+isMan);

       dis.close();

  }
}

 

小结

  1. 流的三种分类方式

    流向:输入流,输出流

    数据单位:字节流,字符流

    流的角色:节点流,处理流

  2. 写出4个IO流中的抽象基类,4个文件流,4个缓冲流

    抽象基类:InputStream,OutputStream,Reader,Writer

    文件流:FileReader、FileWriter、FileInputStream、FileOutputStream

    缓冲流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter

  3. 字节流与字符流的区别与使用情景。

    区别:字节流:一个个字节为基本单位,用于处理非文本文件。

    字符流:字符为基本单位,用于处理文本文件。

     

  4. 使用缓冲流实现a.jpg文件复制为b.jpg文件的操作

    上面的代码有。👆👆👆👆👆👆👆👆👆

  5. 转换流是那两个类,分别的作用是上面?请分别创建两个类的对象。

InputStreamReader:将输入的字节流转换为输入的字符流。解码

OutputStreamWriter:将输出的字符流转换为输出的字节流。 编码

InputStreamReader  isr  =new InputStreamReader(new FileInputStream("a.txt"),"gbk")
   //这里的"gbk"取决于存储时的编码集。
OutputStreamWriter osw =new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8")
   //这里的"UTF-8"自己绝定,想输出什么就输出什么。

 

posted @ 2021-04-06 15:57  独眼龙  阅读(81)  评论(0)    收藏  举报