在复制大文件时,如何与进度条关联起来,有没有简单的办法?

时间:2022-09-14 22:21:43
在复制大文件时,如何与进度条关联起来,有没有简单的办法?

9 个解决方案

#1


这个是系统自带的,我用过..供参考 

   HWND m_hWnd=Form1->Handle;
     char  strTitle[]="File copying";
    SHFILEOPSTRUCT FileOp;
     FileOp.hwnd=m_hWnd;
     FileOp.wFunc=FO_COPY;
     //执行文件拷贝
     FileOp.fFlags=FOF_NOCONFIRMATION;
     FileOp.hNameMappings=NULL;
     FileOp.lpszProgressTitle=strTitle;

     String sF;
     sF=源目录;
        FileOp.pFrom=sF.c_str();

         desc=目的目录;
     FileOp.pTo=desc.c_str();
     nOk=SHFileOperation(&FileOp);

        if(nOk)
               ShowMessage("文件复制出错");
          else
                 ShowMessage("成功");
               }

#2


(总字节-已复制字节数)/(已复制字节数/使用时间)  
  先算出平均速率然后在计算剩余时间,你可以没隔5苗算一次。

#3


void __fastcall TForm1::mCopyFile(AnsiString FileName,AnsiString DestName,TProgressBar *ProgressBar)
{

  TMemoryStream *CopyBuffer=new TMemoryStream;
  long BytesCopied;
  int Source,Dest;
  TFileName Destination;
  const int ChunkSize=8192;

  struct stat statbuf;
  /* 获取文件的大小*/
  FILE *FromF ;
  FromF = fopen(FileName.c_str(),"rb");
  fstat(fileno(FromF), &statbuf);
  int ModVal = statbuf.st_size % ChunkSize;
  int MaxVal = statbuf.st_size / ChunkSize;
  if (ModVal) MaxVal++;
  fclose(FromF);

  ProgressBar->Max = MaxVal;
  ProgressBar->Step=1;
  Destination=ExpandFileName(DestName);
  CopyBuffer->SetSize(ChunkSize);
  Source=FileOpen(FileName,fmOpenRead);
  Dest=FileCreate(Destination);


  do{
    BytesCopied=FileRead(Source,CopyBuffer->Memory,ChunkSize);
    if(BytesCopied>0)
      {
      FileWrite(Dest,CopyBuffer->Memory,BytesCopied);
      }
    ProgressBar->StepIt();
    }
  while(BytesCopied>=ChunkSize);
  FileClose(Source);
  FileClose(Dest);

  delete  CopyBuffer;


}

#4


用代码片段,清晰点


void __fastcall TForm1::mCopyFile(AnsiString FileName,AnsiString DestName,TProgressBar *ProgressBar)
{

  TMemoryStream *CopyBuffer=new TMemoryStream;
  long BytesCopied;
  int Source,Dest;
  TFileName Destination;
  const int ChunkSize=8192;

  struct stat statbuf;
  /* 获取文件的大小*/
  FILE *FromF ;
  FromF = fopen(FileName.c_str(),"rb");
  fstat(fileno(FromF), &statbuf);
  int ModVal = statbuf.st_size % ChunkSize;
  int MaxVal = statbuf.st_size / ChunkSize;
  if (ModVal) MaxVal++;
  fclose(FromF);

  ProgressBar->Max = MaxVal;
  ProgressBar->Step=1;
  Destination=ExpandFileName(DestName);
  CopyBuffer->SetSize(ChunkSize);
  Source=FileOpen(FileName,fmOpenRead);
  Dest=FileCreate(Destination);


  do{
    BytesCopied=FileRead(Source,CopyBuffer->Memory,ChunkSize);
    if(BytesCopied>0)
      {
      FileWrite(Dest,CopyBuffer->Memory,BytesCopied);
      }
    ProgressBar->StepIt();
    }
  while(BytesCopied>=ChunkSize);
  FileClose(Source);
  FileClose(Dest);

  delete  CopyBuffer;


}



#5


up

#6


不外乎:
    1.用API带进程回调的COPYEX语句,没试过,好象不支持所有WONDOWS环境;
    2.用分块复制,每一块时,显示一下进度,有时很有效;但奇怪的时,WINDOWS下有时这样
       复制会莫明奇妙出错;
    3.用普通的COPY,整体复制,把这放进线程中,再用定时器控制进度条,假假的显示进度值,
      但进度的最大值到90%就停,否则穿邦,这只是安慰等侍的用户,没法估计进度时,也可这么干.

#7


SHFileOperation有复制进度条

#8


SHFileOperation 

FileOp.fFlags=FOF_NOCONFIRMATION; 
这个标志只要不给指示安静偷偷的复制都会出来的, 就是操作系统的复制.好用赞一个.

#9


wangfp40 代码的不错!!!要的其实就是这个!
下面改写进度窗口的提示串,不想让客户看到目的目录地址!
//     NetCancel(sharePath);
//     NetConnect(sharePath,username2,passwd);

       String f1="e:\\software\\GX Developer Version 7.0.rar";
       String f2=String(sharePath)+"\\GX Developer Version 7.0.rar";

       HWND m_hWnd=this->Handle;
       SHFILEOPSTRUCT FileOp;
       FileOp.hwnd=m_hWnd;
       FileOp.wFunc=FO_COPY;
       //执行文件拷贝
        FileOp.fFlags=FOF_NOCONFIRMATION|FOF_SIMPLEPROGRESS;
       FileOp.hNameMappings=NULL;
       FileOp.lpszProgressTitle="文件正在传送......" ;
       FileOp.pFrom=f1.c_str();       // 源目录;
       FileOp.pTo=f2.c_str();         // 目的目录;
       int nOk=SHFileOperation(&FileOp);

       if(nOk)
           ShowMessage("文件复制出错");
       else
           ShowMessage("成功");

#1


这个是系统自带的,我用过..供参考 

   HWND m_hWnd=Form1->Handle;
     char  strTitle[]="File copying";
    SHFILEOPSTRUCT FileOp;
     FileOp.hwnd=m_hWnd;
     FileOp.wFunc=FO_COPY;
     //执行文件拷贝
     FileOp.fFlags=FOF_NOCONFIRMATION;
     FileOp.hNameMappings=NULL;
     FileOp.lpszProgressTitle=strTitle;

     String sF;
     sF=源目录;
        FileOp.pFrom=sF.c_str();

         desc=目的目录;
     FileOp.pTo=desc.c_str();
     nOk=SHFileOperation(&FileOp);

        if(nOk)
               ShowMessage("文件复制出错");
          else
                 ShowMessage("成功");
               }

#2


(总字节-已复制字节数)/(已复制字节数/使用时间)  
  先算出平均速率然后在计算剩余时间,你可以没隔5苗算一次。

#3


void __fastcall TForm1::mCopyFile(AnsiString FileName,AnsiString DestName,TProgressBar *ProgressBar)
{

  TMemoryStream *CopyBuffer=new TMemoryStream;
  long BytesCopied;
  int Source,Dest;
  TFileName Destination;
  const int ChunkSize=8192;

  struct stat statbuf;
  /* 获取文件的大小*/
  FILE *FromF ;
  FromF = fopen(FileName.c_str(),"rb");
  fstat(fileno(FromF), &statbuf);
  int ModVal = statbuf.st_size % ChunkSize;
  int MaxVal = statbuf.st_size / ChunkSize;
  if (ModVal) MaxVal++;
  fclose(FromF);

  ProgressBar->Max = MaxVal;
  ProgressBar->Step=1;
  Destination=ExpandFileName(DestName);
  CopyBuffer->SetSize(ChunkSize);
  Source=FileOpen(FileName,fmOpenRead);
  Dest=FileCreate(Destination);


  do{
    BytesCopied=FileRead(Source,CopyBuffer->Memory,ChunkSize);
    if(BytesCopied>0)
      {
      FileWrite(Dest,CopyBuffer->Memory,BytesCopied);
      }
    ProgressBar->StepIt();
    }
  while(BytesCopied>=ChunkSize);
  FileClose(Source);
  FileClose(Dest);

  delete  CopyBuffer;


}

#4


用代码片段,清晰点


void __fastcall TForm1::mCopyFile(AnsiString FileName,AnsiString DestName,TProgressBar *ProgressBar)
{

  TMemoryStream *CopyBuffer=new TMemoryStream;
  long BytesCopied;
  int Source,Dest;
  TFileName Destination;
  const int ChunkSize=8192;

  struct stat statbuf;
  /* 获取文件的大小*/
  FILE *FromF ;
  FromF = fopen(FileName.c_str(),"rb");
  fstat(fileno(FromF), &statbuf);
  int ModVal = statbuf.st_size % ChunkSize;
  int MaxVal = statbuf.st_size / ChunkSize;
  if (ModVal) MaxVal++;
  fclose(FromF);

  ProgressBar->Max = MaxVal;
  ProgressBar->Step=1;
  Destination=ExpandFileName(DestName);
  CopyBuffer->SetSize(ChunkSize);
  Source=FileOpen(FileName,fmOpenRead);
  Dest=FileCreate(Destination);


  do{
    BytesCopied=FileRead(Source,CopyBuffer->Memory,ChunkSize);
    if(BytesCopied>0)
      {
      FileWrite(Dest,CopyBuffer->Memory,BytesCopied);
      }
    ProgressBar->StepIt();
    }
  while(BytesCopied>=ChunkSize);
  FileClose(Source);
  FileClose(Dest);

  delete  CopyBuffer;


}



#5


up

#6


不外乎:
    1.用API带进程回调的COPYEX语句,没试过,好象不支持所有WONDOWS环境;
    2.用分块复制,每一块时,显示一下进度,有时很有效;但奇怪的时,WINDOWS下有时这样
       复制会莫明奇妙出错;
    3.用普通的COPY,整体复制,把这放进线程中,再用定时器控制进度条,假假的显示进度值,
      但进度的最大值到90%就停,否则穿邦,这只是安慰等侍的用户,没法估计进度时,也可这么干.

#7


SHFileOperation有复制进度条

#8


SHFileOperation 

FileOp.fFlags=FOF_NOCONFIRMATION; 
这个标志只要不给指示安静偷偷的复制都会出来的, 就是操作系统的复制.好用赞一个.

#9


wangfp40 代码的不错!!!要的其实就是这个!
下面改写进度窗口的提示串,不想让客户看到目的目录地址!
//     NetCancel(sharePath);
//     NetConnect(sharePath,username2,passwd);

       String f1="e:\\software\\GX Developer Version 7.0.rar";
       String f2=String(sharePath)+"\\GX Developer Version 7.0.rar";

       HWND m_hWnd=this->Handle;
       SHFILEOPSTRUCT FileOp;
       FileOp.hwnd=m_hWnd;
       FileOp.wFunc=FO_COPY;
       //执行文件拷贝
        FileOp.fFlags=FOF_NOCONFIRMATION|FOF_SIMPLEPROGRESS;
       FileOp.hNameMappings=NULL;
       FileOp.lpszProgressTitle="文件正在传送......" ;
       FileOp.pFrom=f1.c_str();       // 源目录;
       FileOp.pTo=f2.c_str();         // 目的目录;
       int nOk=SHFileOperation(&FileOp);

       if(nOk)
           ShowMessage("文件复制出错");
       else
           ShowMessage("成功");