zoukankan      html  css  js  c++  java
  • java中的IO流之文件复制

    O(∩_∩)O哈哈~

    1.综述

    一门成熟的语言肯定具备的几个模块:IO,通信,线程,UI......

    Java作为一门成熟的程序语言,其IO流是比较复杂的。上个图大家感受下:

     

    简单分析一下,IO分为两种流:字符流和字节流。字符流的父类Reader(读取到内存)和Writer(从内存输出),字节流的父类InputStream(读取到内存)和OutputStream(从内存输出),然后为了方便各种操作,比如为了文件操作,派生了文件流;为了对象操作,派生了对象流;等等。当初我也是傻傻分不清到底是Input还是Output,其实搞懂了谁是主体就容易懂了,以你现在正在写的程序为主体,Input就是流入你的程序,Output就是从你的程序流出去。

    2.对于缓冲的理解

    刚开始学IO时,不理解那个Buffered究竟有什么作用,为什么要输入输出总要有一步缓冲过渡呢?后来还是看了百度知道上一个大神写的,个人觉得很有道理,复制粘贴如下,应该不算侵权吧(⊙﹏⊙)

    “如果是边读边写,就会很慢,也伤硬盘。缓冲区就是内存里的一块区域,把数据先存内存里,然后一次性写入,类似数据库的批量操作,这样效率比较高。

    调用IO操作的时候,实际上还是一个一个的读或者写,关键就在,CPU只有一个,不论是几个核心。CPU在系统调用时,会不会还要参与主要操作?参与多次就会花更多的时间。 

    系统调用时,若不用缓冲,CPU会酌情考虑使用 中断。此时CPU是主动地,每个周期中都要花去一部分去询问IO设备是否读完数据,这段时间CPU不能做任何其他的事情(至少负责执行这段模块的核不能)。所以,调用一次读了一个字,通报一次,CPU腾出时间处理一次。 

    而设置缓冲,CPU通常会使用 DMA 方式去执行 IO 操作。CPU 将这个工作交给DMA控制器来做,自己腾出时间做其他的事,当DMA完成工作时,DMA会主动告诉CPU“操作完成”。这时,CPU接管后续工作。在此,CPU 是被动的。DMA是专门 做 I\O 与 内存 数据交换的,不仅自身效率高,也节约了CPU时间,CPU在DMA开始和结束时做了一些设置罢了。 
    所以,调用一次,不必通报CPU,等缓冲区满了,DMA 会对C PU 说 “嘿,伙计!快过来看看,把他们都搬走吧”。 

    综上,设置缓冲,就建立了数据块,使得DMA执行更方便,CPU也有空闲,而不是呆呆地候着IO数据读来。从微观角度来说,设置缓冲效率要高很多。尽管,不能从这个程序上看出来。 几万字的读写就能看到差距。”

    OK,从以上可以看出,省时省力。

    3.文件复制

    文件复制的原理很简单,从硬盘读取文件流到程序,再从程序中输出流到目标文件,就完成了文件的复制。事实上用到了java中的文件输入输出流。看着代码挺多,其实忽略那些try-catch及异常处理,很简单的几行代码。

     1 package test0713;
     2 
     3 import java.io.*;
     4 
     5 public class Manage {
     6     private InputStream input;
     7     private OutputStream output;
     8     private static int length;
     9 /**
    10      * 文件的复制
    11      * 
    12      * @param beginFilename
    13      *            原始文件
    14      * @param endFilename
    15      *            目标文件
    16      */
    17     public void fileCopy(String beginFilename, String endFilename) {
    18         // 创建输入输出流对象
    19         try {
    20             input = new FileInputStream(beginFilename);
    21             output = new FileOutputStream(endFilename);
    22 
    23             // 获取文件长度
    24             try {
    25                 length = input.available();
    26 
    27                 // 创建缓存区域
    28                 byte[] buffer = new byte[length];
    29                 // 将文件中的数据写入缓存数组
    30                 input.read(buffer);
    31                 // 将缓存数组中的数据输出到文件
    32                 output.write(buffer);
    33 
    34             } catch (IOException e) {
    35 
    36                 e.printStackTrace();
    37             }
    38 
    39         } catch (FileNotFoundException e) {
    40             e.printStackTrace();
    41 
    42         } finally {
    43             if (input != null && output != null) {
    44                 try {
    45                     input.close(); // 关闭流
    46                     output.close();
    47                 } catch (IOException e) {
    48                     e.printStackTrace();
    49                 }
    50             }
    51 
    52         }
    53     }
    54 
    55     public static void main(String[] args) {
    56         Manage man = new Manage();
    57         // 第一个参数是将要复制的文件,第二个参数是输出的目标文件(如果没有,则新建一个,实现文件的复制)
    58         man.fileCopy("F:\CodeWorkSpace\java\FileCopy\src\test0713\Manage.java",
    59                 "C:\Users\yuxiu\Desktop\123.txt");
    60 
    61     }
    62 
    63 }
  • 相关阅读:
    懒懒的~~
    BigDecimal,注解
    遇到的一点问题些
    npm一点点
    TortoiseSvn问题研究(一)
    关于maven-基本
    HttpServletRequest二三事
    学习迭代1需求分析
    FMDB简单使用
    计算机中的事务、回滚
  • 原文地址:https://www.cnblogs.com/yuxiuyan/p/5753949.html
Copyright © 2011-2022 走看看