我想做一个文件分割工具!要如何实现!解决就给分
有源代码更佳!
说说思路也行!

解决方案 »

  1.   

    用VC++5.0编写文件分割工具 
    --------------------------------------------------------------------------------  在实际工作中,经常会遇到一些比较大而自己又非常需要的文件,并且必须通过软盘来进行转移。这时候就必须对该文件进行分割,然后分盘拷贝,最后再恢复。如果手头没有相应的分割软件,那就麻烦了。不过,如果您机器里装有VC++5.0,并具备一定VC++5.0编程的知识,就完全可以编写出自己的分割工具,还可以根据个人的喜好,设计出具有自己风格的用户界面。
      前不久,笔者就用VC++5.0编写了一个自己的分割软件。通过多次分割试验,效果还可以,完全可以实现对文件的分割处理。以下就是整个软件的编写过程。
      一. 文件分割的基本原理
      文件之所以能够被分割,是与文件在计算机里的存储方式密切相关的,大家都知道,所有文件都是以二进制的形式存储于介质(包括硬盘、软盘等外部存储器)之中。计算机在读取文件时,总是把数据转化成二进制的形式,然后再根据文件系统的相应规定来分别进行处理。具体的说明可参见相关资料。基于这个道理,所有文件都可以以二进制的格式进行读写、分割,然后再以二进制的格式把分割后的文件重新组合起来。这样就实现了对文件的分割和恢复。这里要用到一个DOS的内部命令——COPY,具体用法如下:
      copy filename1/b+filename2/b+
      …+filenameN/b filename
      这里,开关选项b是指以二进制的形式对文件进行拷贝;filenameN是被分割成的N个文件;filename是组合后的文件名,一般同原文件名。
      二. 程序编写过程及禅解
      1.先创建一个名为Splite的工程文件,利用AppWizard生成一个基于对话框的程序框架。对话框具有如图所示的各类控件。其中,编辑框1要求输入要被分割的文件名,可以通过浏览按钮选择;列表框2能够显示分割后的文件列表;编辑框3显示分割成的文件数,也就是需要的软盘数;要分割的文件被选择之后,按下分割按钮,即可进行分割操作。
      2.程序编写
      (1).使用Class Wizard的Member Variables 制表页给编辑框1(ID号为:IDC_EDIT_FILENAME)添加变量m_fName。
      (2).在SpliteDlg.h里加上下面程序段阴影部分的代码。
      class CSpliteDlg : public CDialog
      {
      // Construction
      public:
       CSpliteDlg(CWnd* pParent = NULL); // standard constructor
       CString SplitFileName[20],FileTitle;
       DWORD FileLength,SingleDisk;
       BOOL FileState;
       int DiskNum;
      // Dialog Data
       //{{AFX_DATA(CSpliteDlg)
       enum { IDD = IDD_SPLITE_DIALOG };
       CString m_fName;
       //}}AFX_DATA
       int SplitDiskNum(CFile &files);
       BOOL SpliteFiletoNum(CFile &file);
      SplitFileName[20]是分割后的文件名数组,这里定义为20个;FileTitle是除去后缀的文件名;FileLength是要分割的文件长度;布尔量FileState是判断分割是否成功的标志,成功则在列表框2中显示分割后的文件列表;整型数DiskNum是指分割后的文件数。
      函数SplitDiskNum(CFile &files)对要分割的文件进行判断,并返回分割后的文件数(也就是需要的软盘数);函数SpliteFiletoNum(CFile &file)将完成文件的分割过程,成功则返回TURE,否则返回FALSE。
      (3).打开SpliteDlg.cpp,在SpliteDlg.cpp里添加上述函数和其它功能的实现代码。如下:
      a.在构造函数中添加以下阴影处代码
       SingleDisk=2048*705; //一张软盘的容量
       FileState=FALSE;
       DiskNum=1;
      b.在OnPaint(CDC *pDC)函数末尾添加以下代码:
      UpdateData(FALSE); //初始化编辑框1的变量
       GotoDlgCtrl(GetDlgItem(IDC_EDIT_FILENAME)); //将光标指定到编辑框1中
       CListBox *pList =(CListBox *) GetDlgItem(IDC_LIST_RESULT); 
      //设置列表框2的ClistBox对象指针
       pList->ResetContent(); //重新设置列表框内容
       if(FileState==TRUE) //文件分割成功
       {
       for(i=0;i<=disknum;i++)
       pList->AddString(SplitFileName[i]); //向列表框中添加分割后的文件名
       }
      c.利用Class Wizard添加&ldquo;浏览&rdquo;按钮的响应函数,代码如下:
      void CSpliteDlg::OnButtonBrowse() 
      {
      char Filter[]=&ldquo;所有文件(*.*)|*.*||";
      CFileDialog dlgOpen(TRUE,0,0,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST,
      (LPCTSTR)Filter,NULL);
      if(dlgOpen.DoModal()==IDOK)
      {
       m_fName=dlgOpen.GetPathName();
       FileTitle=dlgOpen.GetFileName(); //取得要分割的文件名(不包含路径、扩展名)
      }
      else return ;
      SetDlgItemText(IDC_EDIT_FILENAME, (LPCTSTR)m_fName); //在编辑框1中显示文件名
      SetDlgItemText(IDC_EDIT_DISKNUM, _T(&ldquo;")); //在编辑框3中覆盖前次操作的文件数
      Invalidate(TRUE); //对对话框窗口进行重画
      }
      d.利用Class Wizard添加&ldquo;分割&rdquo;按钮的响应函数,代码如下:
      void CSpliteDlg::OnButtonSplite() 
      {
       CFile files;
       CFileException fe;
       if (!files.Open(m_fName, CFile::modeRead | CFile::shareDenyWrite, &fe))
       {
       CString sMsg;
       sMsg.Format(&ldquo;读取%s文件时发生错误!",m_fName);
       AfxMessageBox(sMsg,MB_OK,0);
       return ;
       }
       int i;
       DiskNum=SplitDiskNum(files);
       CString sMsg;
       if(DiskNum>=2)
       {
       sMsg.Format(&ldquo;%d",DiskNum);
       SetDlgItemText(IDC_EDIT_DISKNUM, (LPCTSTR)sMsg); //在编辑框3中显示文件数
      进 if(SpliteFiletoNum(files)==0) //调用分割函数行分割操作
       {
       AfxMessageBox(&ldquo;分割文件失败!",MB_OK,0);
       }
       else 
       {
       AfxMessageBox(&ldquo;分割文件成功!",MB_OK,0);
       FileState=TRUE; //分割成功,设置成功标志
       Invalidate(TRUE);
       }
       }
       else return;
       files.Close(); //关闭打开的被分割文件
      }
      添加函数SplitDiskNum(CFile &files)代码如下:
      int CSpliteDlg::SplitDiskNum(CFile &files)
      {
       int DiskNum;
       FileLength=files.GetLength(); //取得要分割文件的长度
       if(FileLength<=singledisk)
       {
       AfxMessageBox(&ldquo;该文件能被一张盘复制,不必分割!",MB_OK,0);
       DiskNum=0;
      }
       else DiskNum=FileLength/SingleDisk+1; //计算分割后的文件数
      return DiskNum;
      }
      添加函数SpliteFiletoNum(CFile &file)代码如下:
      BOOL CSpliteDlg::SpliteFiletoNum(CFile &file)
      {
       BOOL Success=FALSE;
       int i;
       DWORD dwBitsSize=SingleDisk; // dwBitsSize是指写入文件的字节数
       CFile filed;
       CString FileNum;
      //开辟数据缓冲区,大小为一张软盘的容量
       HANDLE filedate;
       filedate = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,SingleDisk);
       unsigned char * imgtemp;
       imgtemp=(unsigned char *)::GlobalLock((HGLOBAL)filedate);
      //对文件进行分割,并写入分割后的文件中
       for(i=1;i<=disknum;i++)
       {
       FileNum.Format(&ldquo;%d.%d",i,i);
       SplitFileName[i-1]=FileTitle+FileNum;
       if(i==DiskNum) dwBitsSize =FileLength-(DiskNum-1)*SingleDisk;
       file.Seek(SingleDisk*(i-1),CFile::begin);
       if(file.ReadHuge(imgtemp, dwBitsSize)!= dwBitsSize)
       return FALSE;
       filed.Open(SplitFileName[i-1],CFile::modeCreate|CFile::modeWrite,0);
       filed.WriteHuge(imgtemp, dwBitsSize);
       filed.Close();
       }
       if(i==(DiskNum+1)) Success=TRUE; //判断分割是否成功
      //创建合并文件的批处理文件
       FileNum=_T(&ldquo;.bat");
       SplitFileName[DiskNum]=FileTitle+FileNum;
       filed.Open(SplitFileName[DiskNum],CFile::modeCreate|CFile::modeWrite,0);
       CString BatContent=_T(&ldquo;copy ");
       CString BatFile[20];
       for(i=0;i    {
       BatFile[i]=SplitFileName[i]+_T(&ldquo;/b");
       BatContent+=BatFile[i];
       if(i!=DiskNum-1) BatContent+=_T(&ldquo;+");
       else BatContent+=_T(&ldquo; ");
       }
       BatContent+=m_fName;
      //按照&ldquo;copy filename1/b+filename2/b+&hellip;+filenameN/b filename&rdquo;的顺序写入批处理
       for(i=0;i    {
       unsigned char ch=BatContent[i];
       filed.Write(&ch,1);
       }
       return Success;
      filed.Close();
      }
      以上是该程序的主要代码,在VC++5.0下通过编译后,将生成可执行文件Split.exe。该程序只是实现了对文件的分割处理,读者也可以根据个人需要,设计出自己喜好的界面风格,还可以加入其它相关的功能。本文旨在起到抛砖引玉的作用,给广大读者以启发,希望大家都能编写出功能强大并且属于自己的分割软件。
      (天津 房超)
      

  2.   

    分割后,可用dos的命令做一个批处理合并,不用专门的程序
      

  3.   

    VB6二进制双通道技术实战经典 
    (一)编程原理: 
      文件分割实际上就是将目标文件用二进制读写的方法,精确的连续保存为合适大小的独立文件,一般来说,分割后的文件在正确组装前是不能被使用的。 
      文件还原是文件分割的逆过程,即是将分割后的文件严密的按照分割顺序用二进制读写的方法写入一个同一个文件的过程,只要程序算法和逻辑正确严密,分割前和分割后的文件是没有一个字节的差别的。 
      之所以使用双通道技术是因为当被分割的文件较大或者非常大(远远大于内存)时,使用单个文件通道定义的内存二进制缓冲数组非常容易造成内存的用尽而导致操作失败,另一方面,它的处理速度和可靠性也是非常令人担忧的。 
      编程思路是,首先使用双通道技术将目标文件分割成指定大小的文件,扩展名依次是“指定文件名+.源文件扩展名+.分割序号”,并且生成一个还原信息文件“被分割文件名.hj”,该文件将记录文件分割的有关信息;文件还原时,同样利用双通道,按照在还原信息文件中登记的信息,将待还原的文件写入同一个文件中。 
      (二)编程实践: 
      (1)启动vb6,建立一个标准exe工程,添加一个窗体form1,添加microsoft common dialog control 6.0控件,命名为cod1;添加两个frame控件(frame1的caption=“文件分割”,frame2的caption=“文件还原”);添加五个标签框,caption属性依次为“被分割文件名”、“分割后文件大小”、“分割后文件保存在”、“单位:bytes字节”、“还原信息文件名”、“还原后文件保存在”;由上至下一次添加四个caption=“浏览...”的命令按钮command1、command2、command3、command4;由上至下依次添加5个textbox按钮txtFileName、txtFileLength、Txtoutname、txtTemplateName、txtOutputFile;添加两个命令按钮cmdsplit,caption=“开始分割”、cmdunsplit,caption=“开始还原”;两个命令按command5、command6用来指示操作执行进度。代码如下: 
      Option Explicit 
      Private Sub cmdSplit_Click() ’文件分割 
      Dim err_descr As String ’定义接收返回错误码的字符串变量 
      If Not SplitFile(txtFileName.Text,0,err_descr,CLng(txtFileLength.Text),Txtoutname.Text) Then 
      MsgBox "文件操作产生了错误——" & err_descr,vbExclamation 
      Else 
      MsgBox "文件分割操作已经圆满完成!" 
      End If 
      End Sub ’当splitfile公用过程返回值=true表示操作成功,否则失败并返回错误简短的提示 
      Private Sub cmdUnsplit_Click() ’文件还原 
      Dim err_descr As String 
      If Not ReassembleFile(txt TemplateName.Text,False,txtOutputFile.Text) Then 
      MsgBox "文件操作产生了错误——" & err_descr,vbExclamation 
      Else 
      MsgBox "文件还原操作已经圆满完成!" 
      End If 
      End Sub ’当ReassembleFile公用过程返回值=true表示操作成功,否则失败并返回错误简短的提示 
      Private Sub Command1_Click() ’选择被分割文件 
      CoD1.Filter="所有格式文件*.*|*.*" 
      CoD1.ShowOpen 
      If CoD1.FileName<>"" Then 
      txtFileName.Text=CoD1.FileName 
      End If ’如果未选中文件就退出过程 
      End Sub 
      Private Sub Command2_Click() ’分割后文件保存路径名称 
      With CoD1 
      If txtFileName.Text="" Then 
      MsgBox "请首先选择一个被分割文件!" 
      Exit Sub 
      End If ’如果未选定被分割文件退出过程 
      .ShowSave 
      If .FileName<>"" Then 
      Txtoutname.Text=.FileName 
      End If ’如果未指定保存文件名退出 
      End With 
      End Sub 
      Private Sub Command3_Click() ’传回还原信息文件名 
      With CoD1 
      .FileName="" 
      .Filter="还原信息文件*.hj|*.hj" ’只显示*.hj还原信息文件 
      .ShowOpen 
      If .FileName<>"" Then 
      txtTemplateName.Text=.FileName 
      End If 
      End With 
      End Sub 
      Private Sub Command4_Click() ’得到并计算还原后文件名、扩展名 
      Dim g 
      With CoD1 
      If txtTemplateName.Text="" Then 
      MsgBox "请首先选择一个还原信息文件!" 
      Exit Sub ’如果还原信息文件未被选中,则退出过程 
      End If 
      .Filter="" 
      .FileName="" ’清空过期文件名和类型指针 
      .ShowSave 
      If .FileName<>"" Then 
      g=InStr(1,txtTemplateName.Text,".") ’查找第一个“.” 
      txtOutputFile.Text=.FileName & Mid 
      (txtTemplateName.Text,g,4) ’返回文件的用户指定名称和原扩展名 
      End If 
      End With 
      End Sub 
      Private Sub Form_Load() 
      Me.Left=(Screen.Width-Me.Width)/2 
      Me.Top=(Screen.Height-Me.Height)/2 ’窗体居中 
      Me.Caption=App.Title ’初始化标题栏 
      End Sub ’主程序结束 
      (2)添加一个模块Module1,其中包含各种算法具体实现过程,双击模块写入以下代码: 
      Type FileSection 
      Bytes() As Byte 
      End Type ’定义实际内存数组 
      Type SectionedFile 
      Files() As FileSection 
      End Type ’定义辅助内存数组,以备扩展使用 
      Type FileInfo 
      OrigProjSize As Long ’文件大小 
      OrigFileName As String 
      FileCount As Integer 
      FileStartNum As Long 
      End Type ’定义还原信息文件结构参数 
      Public Function SplitFile(SplitFileName As String,BeginningNumber As Long,ReturnErrorDes As String,Split As Long,oName As String) As Boolean 
       
     
      

  4.   

    ’定义公有过程,用来分割文件,函数返回一逻辑值。true代表成功,false代表失败,四个参数依次是,被分割文件名,开始编号,分割后文件大小,分割后文件名称 
      Dim SaveName As String ’分割后文件名 
      Dim fnum As Integer,fnum1 As Integer ’文件通道变量 
      SplitFile=True ’如果下面没有错误,返回真值 
      On Error GoTo CleanUp 
      Dim CurrentFile As SectionedFile,m_lngNumFil As Long,m_LngLoop As Long,FilesLen As Long 
      FilesLen=FileLen(SplitFileName) ’得到被分割文件大小 
      If FilesLen <= Split + 1 Then 
      SplitFile=False 
      ReturnErrorDes="被分割文件大小小于分割后文件大小,请重新设置!" 
      Exit Function 
      End If ’如果被分割文件小于分割后文件,退出过程 
      fnum=FreeFile ’返回第一个空闲通道用来读取 
      Open SplitFileName For Binary As fnum ’用二进制方式打开被分割文件 
      If CInt(FilesLen/Split)>=FilesLen/Split Or CInt(FilesLen/Split)=FilesLen/Split Then 
      m_lngNumFil=CInt(FilesLen/Split) 
      Else 
      m_lngNumFil=CInt(FilesLen/Split)+1 
      End If ’精确计算文件将被分割的个数 
      ReDim CurrentFile.Files(1) ’分配一个内存辅助数组 
      For m_LngLoop=1 To m_lngNumFil 
       ’这个循环用来将文件分割,并且生成分割后的文件 
      If m_LngLoop < m_lngNumFil Then ’如果不是最后一次循环 
      ReDim CurrentFile.Files(1).Bytes(1 To Split) 
      ’ 重新分配大小等于分割尺寸的内存数组 
      Get #fnum,,CurrentFile.Files(1).Bytes 
      ’读取等于分割大小的二进制数据到内存数组 
      Else ’如果是最后一次循环 
      ReDim CurrentFile.Files(1).Bytes To FilesLen-((m_lngNumFil-1)*Split)) 
      ’重新分配大小等于遗留长度的内存数组 
      Get #fnum,,CurrentFile.Files(1).Bytes 
      Close #fnum ’关闭读取文件通道 
      End If 
      SaveName=oName & "." & Format(BeginningNumber-1+m_LngLoop,"00#") ’计算分割后的文件名,扩展名为00? 
      fnum1=FreeFile ’得到第二个空闲通道用来写入 
      Open SaveName For Binary As fnum1 
      Put #fnum1,1,CurrentFile.Files(1) 
      DoEvents 
      Close #fnum1 ’用二进制方式写入分割后的文件 
      Form1.Command6.Caption=FormatPercent(m_LngLoop / m_lngNumFil) ’显示简单的进度指示 
      Form1.Command5.Caption=SaveName ’显示正在操作的文件名 
      Next 
      Dim FileInfoFile As FileInfo ’定义还原信息文件内容 
      FileInfoFile.FileCount=m_lngNumFil ’分割后文件个数 
      FileInfoFile.OrigFileName=oName ’输出文件名 
      FileInfoFile.OrigProjSize=FileLen(SplitFileName) ’被分割文件大小 
      FileInfoFile.FileStartNum=BeginningNumber ’分割后文件起始编号 
      SaveName=oName & ".HJ" ’还原信息文件名 
      fnum=FreeFile 
      Open SaveName For Binary As #fnum 
      Put #fnum,,FileInfoFile 
      Close #fnum ’写入还原信息文件 
      Exit Function 
      CleanUp: ’如果出现错误 
      ReturnErrorDes=Err.Description 
      SplitFile=False ’返回值为false 
      End Function 
      PublicFunctionReassembleFile(Template FileName As String,Optional UseOldFilenameAsBoolean=True,OutPutName as string)As Boolean ’定义文件还原操作公用过程 
      On Error GoTo e 
      Form1.MousePointer=11 
      Dim FileInfo As FileInfo,outname As String,File As SectionedFile,m_LngLoop As Long,OpenName 
      Dim fnum As Integer,fnum1 As Integer 
      ReassembleFile=True 
      fnum=FreeFile 
      Open TemplateFileName For Binary As #fnum 
      Get #fnum,,FileInfo 
      Close #fnum ’读取还原信息文件的有关内容 
      If UseOldFilename Then 
      outname=FileInfo.OrigFileName 
      Else 
      outname=OutPutName 
      End If ’是否自己指定还原后文件名 
      ReDim File.Files(1) 
      fnum1=FreeFile 
      Open outname For Binary As #fnum1 
      For m_LngLoop=1 To FileInfo.FileCount 
      ’通过还原信息中记载的文件个数确定读取次数 
      OpenName=FileInfo.OrigFileName & "." & Format((FileInfo.FileStartNum-1+m_LngLoop),"00#") 
      ’得到分割后生成的文件名称、路径 
      fnum=FreeFile 
      Open OpenName For Binary As #fnum 
      Get #fnum,1,File.Files(1) 
      Close #fnum ’读取 
      Put #fnum1,,File.Files(1).Bytes ’写入 
      Form1.Command6.Caption=FormatPercent(m_LngLoop/FileInfo.FileCount) 
      Form1.Command5.Caption=OpenName 
      Next 
      Close #fnum1 
      Form1.MousePointer=0 
      Exit Function 
      e: 
      MsgBox "文件操作产生了错误:" & Err.Description,vbExclamation 
      ReassembleFile=False 
      Form1.MousePointer=0 
      End Function 
      (三)运行调试: 
      首先通过浏览指定被分割文件名、分割后文件大小、分割后文件名或者还原信息文件名、还原后文件名,然后点击开始分割或者开始还原即可,该程序算法严谨,但是,为了保留一定的扩展能力和对以往源代码的兼容性,也存在一些冗余代码,读者尽可以根据自己的喜好进行改进。另外,使用vb5的朋友注意了,本文函数FormatPercent函数只能在vb6中使用,它的作用是将一个表达式转化成百分数,你必须采用其他的变通方法,其他代码全部通用。
      

  5.   

    Sorry,看错了,这里是Delphi社区:http://www.codechina.net/codelist.asp?id=4545
      

  6.   

    //流合并文件
    function UniteFile(SourceFile,TargetFile:String):Boolean;
    var
    Target,Source: TFileStream;
    MyFileSize: Integer;
    begin
    try
      Source:= TFileStream.Create(SourceFile,fmOpenReadWrite);
      Target:= TFileStream.Create(TargetFile,fmOpenReadWrite);
    try
      Target.Seek(0,soFromEnd);
      Target.CopyFrom(Source,Source.Size);
      MyFileSize:=source.Size;
      Target.WriteBuffer(MyFileSize,SizeOf(MyFileSize));
    finally
      Target.Free;
      Source.Free;
    end;
    except
      Result:= False;
      Exit;
    end;
    Result:= True;
    end;//流文件分解
    function ApartFile(SourceFile,TargetFile:String):Boolean;
    var
    Source: TFileStream;
    Target: TMemoryStream;
    MyFileSize: Integer;
    begin
    try
    Target:= TMemoryStream.Create;
    Source:= TFileStream.Create(SourceFile,fmOpenReadWrite);
    try
      Source.Seek(-sizeof(MyFileSize),soFromEnd);
      Source.ReadBuffer(MyFileSize,SizeOf(MyFileSize));  //读出资源大小
      Source.Seek(-MyFileSize-sizeof(MyFileSize),soFromEnd);  //定位资源位置
      Target.CopyFrom(Source,MyFileSize); //取出资源
      Target.SaveToFile(TargetFile); //存放到文件
    finally
      Source.Free;
      Target.Free;
    end;
    except
      Result:= False;
      Exit;
    end;
    Result:= True;
    end;
      

  7.   

    我买的一本书上有源码,贴给你看看先,需要留油箱传给你
    unit CutFrm;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ExtCtrls, ComCtrls, FileCtrl, ImgList, Buttons
      ,ShellAPI,StrUtils;type
      TForm1 = class(TForm)
        PageCutFile: TPageControl;
        TabSheetCutSize: TTabSheet;
        TabSheetCutFile: TTabSheet;
        TabSheetSelectFile: TTabSheet;
        TabSheetDestDir: TTabSheet;
        SourceDir: TDirectoryListBox;
        FileList: TFileListBox;
        Splitter1: TSplitter;
        Splitter2: TSplitter;
        Panel2: TPanel;
        Drive: TDriveComboBox;
        Label1: TLabel;
        Filter: TFilterComboBox;
        DestDir: TDirectoryListBox;
        DestDrive: TDriveComboBox;
        BtnNew: TButton;
        BtnDelete: TButton;
        Panel3: TPanel;
        Label3: TLabel;
        RadioGroupSize: TRadioGroup;
        ImageList1: TImageList;
        Panel1: TPanel;
        Label2: TLabel;
        STextFilePath: TStaticText;
        Label6: TLabel;
        STextDestPath: TStaticText;
        Label8: TLabel;
        STextFileSize: TStaticText;
        Label9: TLabel;
        STextCutSize: TStaticText;
        LblSizeUnit: TLabel;
        Label10: TLabel;
        Memo: TMemo;
        EdtFileName: TEdit;
        LblDestDir: TLabel;
        SpBtnStart: TSpeedButton;
        ProgressBar: TProgressBar;
        EdtNewDir: TEdit;
        Label11: TLabel;
        Panel5: TPanel;
        Label7: TLabel;
        Label12: TLabel;
        EdtCutSize: TEdit;
        UpDown: TUpDown;
        LblSizeUnit2: TLabel;
        STextFileSize2: TStaticText;
        Label14: TLabel;
        ChkBox: TCheckBox;
        procedure RadioGroupSizeClick(Sender: TObject);
        procedure UpDown1Click(Sender: TObject; Button: TUDBtnType);
        procedure SpBtnStartClick(Sender: TObject);
        procedure FileListDblClick(Sender: TObject);
        procedure PageCutFileChange(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure BtnNewClick(Sender: TObject);
        procedure BtnDeleteClick(Sender: TObject);
        procedure DestDirDblClick(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      
    implementation{$R *.dfm}procedure TForm1.RadioGroupSizeClick(Sender: TObject);
    begin
       case RadioGroupSize.ItemIndex of
          0: EdtCutSize.Text:= '2000' ; //2000 K
          1: EdtCutSize.Text:= '1440' ; //1440 K
          2: EdtCutSize.Text:= '1200' ; //1200 K
          3: EdtCutSize.Text:= '1000' ; //1000 K
          4: EdtCutSize.Text:= '720' ; //720 K
          5: EdtCutSize.Text:= '500' ; //500 K
          6: EdtCutSize.Text:= '300' ; //300 K
          7: EdtCutSize.Text:= '200' ; //200 K
          8: EdtCutSize.Text:= '100' ; //100 K
          else EdtCutSize.Text:= '50' ; //100 K
        end;
    end;procedure TForm1.UpDown1Click(Sender: TObject; Button: TUDBtnType);
    begin
       RadioGroupSize.ItemIndex:=-1;
       EdtCutSize.SetFocus;
    end;procedure TForm1.SpBtnStartClick(Sender: TObject);
    var
       fs:TFileStream;
       ms:TmemoryStream;
       bat:TextFile;
       SaveFileName,BatFileName:string;
       CutSize,FileCount,i:integer;
    begin
    //用一个'文件流' 以只读方式打开原始文件
       fs:=TfileStream.create(STextFilePath.Caption,fmOpenRead);
    // 然后创建一个'内存流'
       ms:=TmemoryStream.create;
    //根据文件切割的大小计算字节数,
       CutSize:=StrToInt(STextCutSize.Caption)*1024;   SaveFileName:=STextDestPath.Caption+'\'
          +ExtractFileName(STextFilePath.Caption);
       FileCount:= 1;   //切割过程中显示一个进度,让用户了解进度,
       ProgressBar.Min:= 0;
       //根据文件大小设定最大最大值和步长
       ProgressBar.Max:= (fs.size div CutSize)+1;
       ProgressBar.step:= 1;   while fs.Position<fs.Size-1 do
       begin
          ms.position:= 0;
          ms.size:= 0;
          if fs.size-fs.Position<CutSize then
             CutSize:=fs.size-fs.position;
          //从'文件流'中向'内存流'中拷贝指定的大小
          ms.CopyFrom(fs,CutSize);
          //响应应用程序其他消息,如让应用程序修改进度条
          //但需注意避免死循环
          application.ProcessMessages;     //在切割过程中不断修改进度条的当前位置,给用户一个运动的状态。
          ProgressBar.StepIt;
         //文件扩展名累计创建(方便合并),
         //并将内存流存储到目标文件夹下
          ms.SaveToFile(ChangeFileExt(SaveFileName,'.'+inttostr(FileCount)));      Memo.lines.add('正在生成第 '+IntToStr(FileCount)+' 个文件!');
          inc(FileCount);
       end;
       fs.Free; {在 Dos 中有一条命令可以完成文件的合并
      Copy file1 /b +file2 /b file3
      所以要生成一个批处理命令文件,就可以在需要的时候能自动完成合并工作}  //生成一个批处理命令文件名
      BatFileName:=STextDestPath.Caption+'\'
          +ChangeFileExt(ExtractFileName(STextFilePath.Caption),'.bat');  AssignFile(bat,BatFileName);
      rewrite(bat);
      writeln(bat,'echo off');
      writeln(bat,'echo 谢谢使用文件分割器 1.0 .....');
      writeln(bat,'echo .');
      writeln(bat,'echo 正在准备生成文件'+ExtractFileName(BatFileName));
      writeln(bat, 'echo .');
      writeln(bat,' echo 按 CTRL + Z 键可以中止,其他键继续!');
      writeln(bat,'pause');  for i := 1 to FileCount + 1 do
      begin
         if i = 1 then
            writeln(bat,'copy '+
            ChangeFileExt(ExtractFileName(SaveFileName),'.1')
            +'/b '+ExtractFileName(SaveFileName))
         else
            writeln(bat,'copy '+ExtractFileName(SaveFileName)+'/b +'
            +ChangeFileExt(ExtractFileName(SaveFileName),'.'+inttostr(i))
            +'/b');
       end;
      

  8.   

    Memo.lines.add('正在生成合并命令文件: '+BatFileName);   closefile(bat);   memo.lines.add('切割成功完成!');
       Application.MessageBox('切割成功完成!','信息框',MB_OK+MB_ICONINFORMATION);end;procedure TForm1.FileListDblClick(Sender: TObject);
    var
       fs:TFileStream;
       AFileSize:Single;
       FileName,NewFolder:string;
       DotPosition:integer;
    begin
       PageCutFile.ActivePage:=TabSheetDestDir;
       DestDir.Directory:=SourceDir.Directory;   FileName:=ExpandFileName(FileList.FileName);
       fs:=TfileStream.create(FileName,fmOpenRead);
       //获得文件大小
       LblSizeUnit2.Caption:='K';
       AFileSize:=fs.Size/1024;   if AFileSize>1000 then
       begin
          AFileSize:=AFileSize/1000;
          LblSizeUnit2.Caption:='M';
       end;
       STextFileSize2.Caption:=FloatToStrF(AFileSize,ffFixed,4,2);
       fs.Free;   NewFolder:=ExtractFileName(FileName);
       DotPosition:=pos('.',NewFolder);
       NewFolder:=Copy(NewFolder,1,DotPosition-1);
       EdtNewDir.Text:=NewFolder;
    end;procedure TForm1.PageCutFileChange(Sender: TObject);
    var
       CanStart:boolean;//判断是否可以开始
       fs:TFileStream;
       AFileSize:Single;
    begin
    //当选择切割文件页面时
    if PageCutFile.ActivePage=TabSheetCutFile then
    begin
       CanStart:=False;
       STextFilePath.Caption:=FileList.FileName;
       STextDestPath.Caption:=DestDir.Directory;
       STextCutSize.Caption:=EdtCutSize.Text;
       if FileExists(STextFilePath.Caption)then
       begin
          CanStart:=True;
          //用一个'文件流' 以只读方式打开原始文件
          //用一个'文件流' 以只读方式打开原始文件,以便获得文件大小
          fs:=TfileStream.create(STextFilePath.Caption,fmOpenRead);
          LblSizeUnit.Caption:='K'; // 文件大小单位为千字节
          AFileSize:=fs.Size/1024; // 获得文件大小,并换算为千字节
          if AFileSize>1000 then // 如果文件大于一千字节,则以兆字节为单位
          begin
             AFileSize:=AFileSize/1000; //将文件大小换算为兆字节
             LblSizeUnit.Caption:='M'; // 显示单位为 M
          end;
          // 函数FloatToStrF 将浮点数转为字符串并格式化输出,保留两位小数
          STextFileSize.Caption:=FloatToStrF(AFileSize,ffFixed,4,2);
          fs.Free; // 释放TfileStream变量所占内存资源
       end
       else begin
          Application.MessageBox('请选取文件!','信息框',MB_OK+MB_ICONINFORMATION);
          PageCutFile.ActivePage:=TTabSheet(TabSheetSelectFile);
       end;
       SpBtnStart.Enabled:=CanStart;
       memo.Lines.Clear;
       ProgressBar.Position:=0;
    end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
       PageCutFile.ActivePageIndex:=0;
    end;procedure TForm1.BtnNewClick(Sender: TObject);
    var
       NewFolder:string;
    begin
    //判断 DestDir.Directory 最右边一个字符是否是 '\'
    //使用RightStr 需要引用单元 StrUtils
       if RightStr(DestDir.Directory,1)='\' then
          NewFolder:=DestDir.Directory+EdtNewDir.Text
       else
    //设置新文件夹路径   
          NewFolder:=DestDir.Directory+'\'+EdtNewDir.Text;   MKDir(NewFolder);
       DestDir.Directory:=NewFolder;
    end;
    procedure DelTree(Folder:string);
    var
       sr:TsearchRec;   //调用FindFirst时所返回的文件信息,参见帮助
    begin
       if FindFirst(Folder+'\*.*',faAnyFile,sr)=0 then
        begin
          repeat        if (sr.Attr and faDirectory)=faDirectory then
                         //判断所找到的文件是否是文件目录
            begin
               if ((sr.Name<>'.')and(sr.Name<>'..')) then
               begin
                  //删除子文件夹
                  DelTree(Folder+'\'+sr.Name);
               end;
            end
            else begin
                //删除文件
               DeleteFile(Folder+'\'+sr.Name);
            end;
          until FindNext(sr) <> 0;
        end;
        FindClose(sr);
        ChDir('..');
        //删除空目录
        RmDir(Folder);
    end;
    procedure TForm1.BtnDeleteClick(Sender: TObject);
    var
       Folder:string;
       opStruct:TSHFileOpStruct;
    begin
       Folder:=DestDir.Directory;
       {if ChkBox.Checked then
       begin
          DestDir.Directory:=Folder+'..';
          with opStruct do begin
              Wnd:=0;
              wFunc:=FO_DELETE;
              pFrom:=PChar(Folder);
              fFlags:=FOF_ALLOWUNDO;
          end;
          SHFileOperation(opStruct);
       end
       else} begin
          if Application.MessageBox(PChar('要删除目录 '+Folder+' 吗?')
             ,PChar('确认信息'),Mb_YesNo)=ID_YES then
          begin
             DelTree(Folder);
             DestDir.Directory:=Folder+'..';
          end;
       end;
    end;procedure TForm1.DestDirDblClick(Sender: TObject);
    begin
    BtnDelete.Enabled:=True;
    end;end.
      

  9.   

    可以用TFileStream,也可以是无类型的File
    效果一样的