Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.05.2011, 13:38   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию Копирование файла(с Gauge) с использованием TfileStream на выходе пишет гигабитных монстов

Всем привет!

Вот искал готовый код копирования файлов с указанием индекатора копирования...

и нашёл:
Код:
Type   
  TCallBack=procedure (Position,Size:Longint); {Для индикации процесса копирования}  
    
procedure FastFileCopy(Const InfileName, OutFileName: String; CallBack: TCallBack);   
Const BufSize = 3*4*4096; { 48Kbytes дает прекрасный результат }  
Type   
  PBuffer = ^TBuffer;   
  TBuffer = array [1..BufSize] of Byte;   
var  
  Size             : integer;   
  Buffer           : PBuffer;   
  infile, outfile  : File;   
  SizeDone,SizeFile: Longint;   
begin  
  if (InFileName <> OutFileName) then  
  begin  
   buffer := Nil;   
   AssignFile(infile, InFileName);   
   System.Reset(infile, 1);   
   try  
     SizeFile := FileSize(infile);   
     AssignFile(outfile, OutFileName);   
     System.Rewrite(outfile, 1);   
     try  
       SizeDone := 0; New(Buffer);   
       repeat  
         BlockRead(infile, Buffer^, BufSize, Size);   
         Inc(SizeDone, Size);   
         CallBack(SizeDone, SizeFile);   
         BlockWrite(outfile,Buffer^, Size)   
       until Size < BufSize;   
       FileSetDate(TFileRec(outfile).Handle,   
         FileGetDate(TFileRec(infile).Handle));   
     finally  
      if Buffer <> Nil then Dispose(Buffer);   
      System.close(outfile)   
     end;   
   finally  
     System.close(infile);   
   end;   
 end else  
  Raise EInOutError.Create('File cannot be copied into itself');   
end;
решил переписать под использование TFileStream;

Вот что получилось:
Код:
procedure FastCopFile(aInFile, aOutFile: string; CallBackProc: TCallBack);
const
  BuffSize = 3 * 4 * 4096; // 48 kb
var
  Buff: array [1 .. BuffSize] of Byte;
  InFile, OutFile: TFileStream;
  fSize: Int64; // File size
  fPosition: Integer; // file position
  cSize: Int64; // Copyed size
begin
  If not(aInFile <> aOutFile) then
  begin
    MessageBox(Application.Handle,
      'Пути входного и выходного файлов совпадают! Копирование невозможно!',
      'Внимание!', MB_OK or MB_ICONWARNING);
    Exit;
  end;

  InFile := TFileStream.Create(aInFile, fmOpenRead);
  OutFile := TFileStream.Create(aOutFile, fmCreate or fmOpenWrite);
  try
    InFile.Seek(0, soFromBeginning);
    OutFile.Seek(0, soFromBeginning);
    fSize := InFile.Size;
    fPosition := 0;
    repeat
      InFile.Read(Buff, BuffSize);
      Inc(fPosition, cSize);
      CallBackProc(fPosition, fSize);
      OutFile.Write(Buff, BuffSize);
    until cSize < BuffSize;
  finally
    InFile.Free;
    OutFile.Free;
  end;
end;
собственно проблема:
Запустил, поставил копировать файл размером 6 мб из одной папки в другую.

Пошёл пить чай. ПРишел, файлик на выходе 7 гб.

Откуда лишние байтики? Что не так делаю?
Человек_Борща вне форума Ответить с цитированием
Старый 28.05.2011, 14:20   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
until cSize < BuffSize;
а где cSize меняется?
Код:
repeat
      cSize:=InFile.Read(Buff, BuffSize);
      Inc(fPosition, cSize);
      CallBackProc(fPosition, fSize);
      OutFile.Write(Buff, BuffSize);
    until cSize < BuffSize;
красный поправка.

а зачем было переписывать то что работало?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 28.05.2011, 14:29   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,434
По умолчанию

там довольно старый способ=) TfileStream как-то проще и новее...

Или это мне только кажется?
Человек_Борща вне форума Ответить с цитированием
Старый 28.05.2011, 15:50   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

в данном случае разницы ноль, все равно сводится к CreateFile,ReadFile,WriteFile,SetFi lePointer,CloseHandle
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение файла с использованием TFileStream Desha Помощь студентам 0 13.05.2011 22:18
WinInet докачка файла через TFileStream Человек_Борща Работа с сетью в Delphi 11 16.08.2010 17:31
Передача файла от клиента к серверу TFileStream rombler69 Работа с сетью в Delphi 1 30.03.2010 17:45
Копирование файла Killbrum Помощь студентам 9 07.09.2009 17:09
прога пишет ошибку при открытии файла (почему?) nicky777 Общие вопросы Delphi 2 14.03.2008 17:56