• JAVA写的文件分割与文件合并程序


      原来觉得文件的切割与合并好神秘,觉得能够写这样程序的人简直就是高手、老鸟之类的人了,呵呵。

      现在我自己这么一写,才觉得是如此之简单,连我这都菜鸟都能够写(不过,还是花了我将近半天的时间,呵呵),看来只要是人都能够写了。

      暂时不懂,没有关系,好好拿去看一下。主要涉及的知识也没有几个,无非就是文件输入输出流、随机文件的读写之类的。其它的就是循环,很简单的,有兴趣的就看看。

      只有两个文件:Separator.java(文件分割)、Combination.java(文件合并)。

    Separator.java(文件分割):

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.RandomAccessFile;

    /**
     * 文件分隔器:给定文件的路径和每一块要拆分的大小,就可以按要求拆分文件
     * 如果指定的块给原文件都还要大,为了不动原文件,就生成另一个文件,以.bak为后缀,这样可以保证原文件
     * 如果是程序自动拆分为多个文件,那么后缀分别为".part序号",这样就可以方便文件的合并了
     * 原理:很简单,就是利用是输入输出流,加上随机文件读取。
     */
    public class Separator
    {
      String FileName=null;//原文件名
      long FileSize=0;//原文件的大小
      long BlockNum=0;//可分的块数
      public Separator()
      {
      }
      /**
       *
       * @param fileAndPath 原文件名及路径
       */
      private void getFileAttribute(String fileAndPath)//取得原文件的属性
      {
        File file=new File(fileAndPath);
        FileName=file.getName();
        FileSize=file.length();
      }
      /**
       *
       * @param blockSize 每一块的大小
       * @return 能够分得的块数
       */
      private long getBlockNum(long blockSize)//取得分块数
      {
        long fileSize=FileSize;
        if(fileSize<=blockSize)//如果分块的小小只够分一个块
          return 1;
        else
        {
          if(fileSize%blockSize>0)
          {
            return fileSize/blockSize+1;
          }
          else
            return fileSize/blockSize;
        }
      }
      /**
       *
       * @param fileAndPath 原文件及完整路径
       * @param currentBlock 当前块的序号
       * @return 现在拆分后块的文件名
       */
      private String generateSeparatorFileName(String fileAndPath,int currentBlock)//生成折分后的文件名,以便于将来合将
      {
        return fileAndPath+".part"+currentBlock;
      }
      /**
       *
       * @param fileAndPath 原文件及完整路径
       * @param fileSeparateName 文件分隔后要生成的文件名,与原文件在同一个目录下
       * @param blockSize 当前块要写的字节数
       * @param beginPos 从原文件的什么地方开始读取
       * @return true为写入成功,false为写入失败
       */
      private boolean writeFile(String fileAndPath,String fileSeparateName,long blockSize,long beginPos)//往硬盘写文件
      {
     
        RandomAccessFile raf=null;
        FileOutputStream fos=null;
        byte[] bt=new byte[1024];
        long writeByte=0;
        int len=0;
        try
        {
          raf = new RandomAccessFile(fileAndPath,"r");
          raf.seek(beginPos);
          fos = new FileOutputStream(fileSeparateName);
          while((len=raf.read(bt))>0)
          {       
            if(writeByte<blockSize)//如果当前块还没有写满
            {
              writeByte=writeByte+len;
              if(writeByte<=blockSize)
                fos.write(bt,0,len);
              else
              {
                len=len-(int)(writeByte-blockSize);
                fos.write(bt,0,len);
              }
            }       
          }
          fos.close();
          raf.close();
        }
        catch (Exception e)
        {
          e.printStackTrace();
          try
          {
            if(fos!=null)
              fos.close();
            if(raf!=null)
              raf.close();
          }
          catch(Exception f)
          {
            f.printStackTrace();
          }
          return false;
        }
        return true;
      }
      /**
       *
       * @param fileAndPath 原文路径及文件名
       * @param blockSize 要拆分的每一块的大小
       * @return true为拆分成功,false为拆分失败
       */
      private boolean separatorFile(String fileAndPath,long blockSize)//折分文件主函数
      {
        getFileAttribute(fileAndPath);//将文件的名及大小属性取出来
        //System.out.println("FileSize:"+FileSize);
        //System.out.println("blockSize:"+blockSize);
        BlockNum=getBlockNum(blockSize);//取得分块总数
        //System.out.println("BlockNum:"+BlockNum);
        //System.exit(0);
        if(BlockNum==1)//如果只能够分一块,就一次性写入
          blockSize=FileSize;
        long writeSize=0;//每次写入的字节
        long writeTotal=0;//已经写了的字节
        String FileCurrentNameAndPath=null;
        for(int i=1;i<=BlockNum;i++)
        {
          if(i<BlockNum)
            writeSize=blockSize;//取得每一次要写入的文件大小
          else
            writeSize=FileSize-writeTotal;
          if(BlockNum==1)
            FileCurrentNameAndPath=fileAndPath+".bak";
          else
            FileCurrentNameAndPath=generateSeparatorFileName(fileAndPath,i);
          //System.out.print("本次写入:"+writeSize);     
          if(!writeFile(fileAndPath,FileCurrentNameAndPath,writeSize,writeTotal))//循环往硬盘写文件
            return false;
          writeTotal=writeTotal+writeSize;
          //System.out.println("  总共写入:"+writeTotal);
        }
        return true;
      }
      public static void main(String[] args)
      {
        Separator separator = new Separator();
        String fileAndPath="d://test.rar";//文件名及路径
        long blockSize=200*1024;//每一个文件块的大小,大小是按字节计算
        if(separator.separatorFile(fileAndPath,blockSize))
        {
          System.out.println("文件折分成功!");
        }
        else
        {
          System.out.println("文件折分失败!");
        }
         
      }
    }

    Combination.java(文件合并):

    /**
     * 合并文件:合并由拆分文件拆分的文件
     * 要求将拆分文件放到一个文件夹中
     * 主要利用随机文件读取和文件输入输出流
     */
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;

    import java.util.Arrays;
    import java.util.StringTokenizer;

    public class Combination
    {
      String srcDirectory=null;//拆分文件存放的目录
      String[] separatedFiles;//存放所有拆分文件名
      String[][] separatedFilesAndSize;//存放所有拆分文件名及分件大小
      int FileNum=0;//确定文件个数
      String fileRealName="";//据拆分文件名确定现在原文件名
      public Combination()
      {
        srcDirectory="d://test//";
      }
      /**
       *
       * @param sFileName 任一一个拆分文件名
       * @return 原文件名
       */
      private String getRealName(String sFileName)
      {
        StringTokenizer st=new StringTokenizer(sFileName,".");
        return st.nextToken()+"."+st.nextToken();
      }
      /**
       * 取得指定拆分文件模块的文件大小
       * @param FileName 拆分的文件名
       * @return
       */
      private long getFileSize(String FileName)
      {
        FileName=srcDirectory+FileName;
        return (new File(FileName).length());
      }
      /**
       * 生成一些属性,做初使化
       * @param drictory 拆分文件目录
       */
      private void getFileAttribute(String drictory)
      {
        File file=new File(drictory);
        separatedFiles=new String[file.list().length];//依文件数目动态生成一维数组,只有文件名
        separatedFiles=file.list();
        //依文件数目动态生成二维数组,包括文件名和文件大小
        //第一维装文件名,第二维为该文件的字节大小
        separatedFilesAndSize=new String[separatedFiles.length][2];
        Arrays.sort(separatedFiles);//排序
        FileNum=separatedFiles.length;//当前文件夹下面有多少个文件
        for(int i=0;i<FileNum;i++)
        {
          separatedFilesAndSize[i][0]=separatedFiles[i];//文件名
          separatedFilesAndSize[i][1]=String.valueOf(getFileSize(separatedFiles[i]));//文件大上
        }
        fileRealName=getRealName(separatedFiles[FileNum-1]);//取得文件分隔前的原文件名
      }
      /**
       * 合并文件:利用随机文件读写
       * @return true为成功合并文件
       */
      private boolean CombFile()
      {
        RandomAccessFile raf=null;
        long alreadyWrite=0;
        FileInputStream fis=null;
        int len=0;
        byte[] bt=new byte[1024];
        try
        {
          raf = new RandomAccessFile(srcDirectory+fileRealName,"rw");
          for(int i=0;i<FileNum;i++)
          {
            raf.seek(alreadyWrite);
            fis=new FileInputStream(srcDirectory+separatedFilesAndSize[i][0]);
            while((len=fis.read(bt))>0)
            {
              raf.write(bt,0,len);
            }
            fis.close();
            alreadyWrite=alreadyWrite+Long.parseLong(separatedFilesAndSize[i][1]);
          }
          raf.close();     
        }
        catch (Exception e)
        {
          e.printStackTrace();
          try
          {
            if(raf!=null)
              raf.close();
            if(fis!=null)
              fis.close();
          }
          catch (IOException f)
          {
            f.printStackTrace();
          }
          return false;
        }
        return true;
      }
      public static void main(String[] args)
      {
        Combination combination = new Combination();   
        combination.getFileAttribute(combination.srcDirectory);
        combination.CombFile();
        System.exit(0);
      }
    }

    再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

  • 相关阅读:
    [CTF]Capture The Flag -- 夺旗赛
    [DesignPattern]Builder设计模式
    [Git]Git 常用的操作命令
    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
    QT 实现 读取 增加 删除 实时操作xml
    QT5-图形视图框架
    C++之QT
    ,即双方交锋的次数。随后N行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C代表“锤子”、J代表“剪刀”、B代表“布”,第1个字母代表甲方,第2个代表乙方,中间有1个空格。
    要获得一个C语言程序的运行时间,常用的方法是调用头文件time.h,其中提供了clock()函数,可以捕捉从程序开始运行到clock()被调用时所耗费的时间。这个时间单位是clock tick,即“时钟打点”。同时还有一个常数CLK_TCK,给
    给定N个非0的个位数字,用其中任意2个数字都可以组合成1个2位的数字。要求所有可能组合出来的2位数字的和。例如给定2、5、8,则可以组合出:25、28、52、58、82、85,它们的和为330。
  • 原文地址:https://www.cnblogs.com/skiwdhwhssh/p/10341697.html
Copyright © 2020-2023  润新知