`

文件拆分

F# 
阅读更多
package com.test3;
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[30*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)
      {       
       System.out.println("---=====>"+len);//30720
    	 if(writeByte<blockSize)//如果当前块还没有写满
        {
          writeByte=writeByte+len;
          if(writeByte<=blockSize)
            fos.write(bt,0,len);
          else
          {
            len=len-(int)(writeByte-blockSize);
            System.out.println("-------------->"+len);//4096
            fos.write(bt,0,len);
          }
        } 
    	 // 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="f:/大唐御医.txt";//文件名及路径
    long blockSize=1024*1024;//每一个文件块的大小,大小是按字节计算
    if(separator.separatorFile(fileAndPath,blockSize))
    {
      System.out.println("文件折分成功!");
    }
    else
    {
      System.out.println("文件折分失败!");
    }
     
  }
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics