Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Копирование файлов не используя ОЗУ 
:(
    Опции темы
livo
Дата 1.11.2009, 03:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Поиски по форуму ответа не дали.
Я знаю такие способы копирования:
  • используя TMemoryStream;
  • используя TFileStream;
  • используя функцию SHFileOperations;
  • используя структуру FILE и методы fread,fwrite;
ну и т.д.

Но, я так понимаю, они загружают данные в буфер перед тем, как отправить содержимое этого буфера на винч. Однако мне бы хотелось производить копирование напрямик: используя только средства жесткого диска. Ведь это быстрее.

Существует ли решение этой задачи?
PM MAIL   Вверх
Lazin
Дата 1.11.2009, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



насколько я понял, тебе нужна ф-я CopyFile

Добавлено через 1 минуту и 57 секунд
Цитата(livo @  1.11.2009,  03:04 Найти цитируемый пост)
Однако мне бы хотелось производить копирование напрямик: используя только средства жесткого диска. Ведь это быстрее.

АФАИК, ф-я CopyFile то-же использует какой-то буфер внутри себя, а то что ты хочешь - вряд-ли возможно, так-как жесткий диск ничего не знает о файловой системе
PM MAIL Skype GTalk   Вверх
livo
Дата 1.11.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Lazin, о функции CopyFile я тоже знаю. По твоим словам выходит, что невозможно скопировать файл не используя какой-то буфер в оперативке.

В таком случае было бы неплохо реализовать алгоритм, позволяющий максимально быстро копировать файлы. Например, как в тотал коммандер (здесь копирование, по-моему, даже быстрее, чем в апи SHFileOperations).

Скоро подготовлю пример.

Вот он (почему-то не работает):
Код

bool __fastcall TForm1::lcopy(String from,String to,bool replace=0)
{
 TFileStream *fsFrom,*fsTo;
 const MAXBUFF=32768;//32 КБ
 char buffer[MAXBUFF];
 bool copied=1;
 int read;
 try
 {
  fsFrom=new TFileStream(from,fmOpenRead|fmShareExclusive);
  if(!replace && FileExists(to))throw Exception("file_exists");
  fsTo=new TFileStream(to,fmCreate|fmShareExclusive);
  ProgressBar1->Position=0;
  ProgressBar1->Max=fsFrom->Size;
  do
  {
    read=fsFrom->Read(buffer,MAXBUFF);
    fsTo->Write(buffer,read);
    ProgressBar1->Position=ProgressBar1->Position+read;
  }while(read);
 }
 catch(Exception&)
 {
   copied=0;
   goto del;
 }
 del:
 if(fsFrom)delete fsFrom;
 if(fsTo)delete fsTo;
 return copied;
}


Это сообщение отредактировал(а) livo - 1.11.2009, 13:43
PM MAIL   Вверх
vikaz
Дата 1.11.2009, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: 10
Всего: 12



Если честно, вопрос очень странный. Такое ощущение, но я надеюсь, что ошибаюсь, что Вы мало знаете устройство компьютера в целом, а в частности устройство и работу жесткого. Даже если бы это и было возможно, то только с двумя жесткими дисками. Но тогда жесткие диски должны были бы уметь коннектиться друг к другу и осуществлять прямое копирование без использование ОС. Я о таком чуде не слышал! А если у Вас используется всего 1 диск, то без буфера тут вообще не обойтись, как Вы себе представляете как 1 головка будет переносить данные из одной области в другую? Еще при копировании должен быть компромисс скорость/буфер выделенный в памяти. 


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
livo
Дата 1.11.2009, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



vikaz, моя задача проста: произвести наиболее быстрое копирование. Вот и все.

Насчет устройства винта, я знаю, что невозможно читать и писать одновременно. Однако я знаю, что жестк. диск имеет собственный буфер. Просто стало интересно: можно ли его использовать в своей программе.
PM MAIL   Вверх
Lazin
Дата 1.11.2009, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Цитата(livo @  1.11.2009,  15:28 Найти цитируемый пост)
 Однако я знаю, что жестк. диск имеет собственный буфер. Просто стало интересно: можно ли его использовать в своей программе. 

им управляет контроллер жесткого диска, никак не ос
что-бы максимально быстро считать и записать файл, нужно читать и записывать в обход системного кэша, считываешь сектор(или сразу несколько) из одного файла, записываешь в другой.
PM MAIL Skype GTalk   Вверх
Alexeis
Дата 1.11.2009, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



  Ну так если подумать. NTFS это файловая система. Про нее жесткий диск ничего не знает, так же как о файлах. Для него нет понятия файла. Самое низкоуровневое что можно сделать, только обратиться к драйверу файловой системы напрямую. Думаю, что функция ReadFile как раз это и делает, по крайней мере ее используют для операций ввода/вывода драйверов.
  На счет копирования файлов хочу поделиться своим опытом. Если физически устройства различные, то буфера 40-100кб будет достаточно. Если это 2е партиции одного винта, то выгодно использовать буфер порядка 10Мб, поскольку в этом случае количество перемещений магнитной головки будет минимальным. 
  Для флешки оптимальный размер гораздо меньше, главное чтобы время на вызовы функции не было дольше операции копирования блока (лучше если не мене десяти раз меньше)


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
livo
Дата 1.11.2009, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Цитата

нужно читать и записывать в обход системного кэша, считываешь сектор(или сразу несколько) из одного файла, записываешь в другой.

Было бы неплохо обойти этот кэш. Но каким образом это можно сделать? smile 
PM MAIL   Вверх
Lazin
Дата 1.11.2009, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Цитата(livo @  1.11.2009,  15:48 Найти цитируемый пост)
Было бы неплохо обойти этот кэш. Но каким образом это можно сделать?

Ф-ии ReadFile/WriteFile, нужно указать флаг FILE_FLAG_NO_BUFFERING, читать и записывать можно будет только порции данных, кратные размеру сектора, вся необходимая информация есть в MSDN, в описании ф-ий ReadFile/WriteFile
PM MAIL Skype GTalk   Вверх
vikaz
Дата 1.11.2009, 20:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 869
Регистрация: 15.2.2006

Репутация: 10
Всего: 12



Цитата(Alexeis @  1.11.2009,  15:46 Найти цитируемый пост)
Ну так если подумать. NTFS это файловая система. Про нее жесткий диск ничего не знает, так же как о файлах. Для него нет понятия файла. Самое низкоуровневое что можно сделать, только обратиться к драйверу файловой системы напрямую. Думаю, что функция ReadFile как раз это и делает, по крайней мере ее используют для операций ввода/вывода драйверов.
  На счет копирования файлов хочу поделиться своим опытом. Если физически устройства различные, то буфера 40-100кб будет достаточно. Если это 2е партиции одного винта, то выгодно использовать буфер порядка 10Мб, поскольку в этом случае количество перемещений магнитной головки будет минимальным. 
  Для флешки оптимальный размер гораздо меньше, главное чтобы время на вызовы функции не было дольше операции копирования блока (лучше если не мене десяти раз меньше) 


Полностью поддерживаю....


--------------------
user posted image

Нет ничего настолько исправного, чтобы в нем не было ошибок. /Ф. Петрарка/ 
PM MAIL ICQ Skype   Вверх
livo
Дата 1.11.2009, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



А можно ли в паре с этими функциями использовать отображение прогресса копирования?
PM MAIL   Вверх
Lazin
Дата 2.11.2009, 06:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 18
Всего: 154



Цитата(livo @  1.11.2009,  23:29 Найти цитируемый пост)
А можно ли в паре с этими функциями использовать отображение прогресса копирования?
можно, если читать и записывать не целиком, а блоками
PM MAIL Skype GTalk   Вверх
Alexeis
Дата 2.11.2009, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



  Если использовать CopyFileEx, то можно воспользоваться параметром LPPROGRESS_ROUTINE lpProgressRoutine и выводить прогресс из калбэка.



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
livo
Дата 3.11.2009, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 104
Регистрация: 14.10.2007

Репутация: 1
Всего: 1



Alexeis, спс за подсказку.
Реализовал такой вот примерчик:
Код

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
bool cancel,pause;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
DWORD CALLBACK progressfun(
  LARGE_INTEGER TotalFileSize,
  LARGE_INTEGER TotalBytesTransferred,
  LARGE_INTEGER StreamSize,
  LARGE_INTEGER StreamBytesTransferred,
  DWORD dwStreamNumber,
  DWORD dwCallbackReason,
  HANDLE hSourceFile,
  HANDLE hDestinationFile,
  LPVOID lpData
 )
{
 if(dwCallbackReason==CALLBACK_STREAM_SWITCH)
 {
   Form1->ProgressBar1->Position=0;
   Form1->ProgressBar1->Max=TotalFileSize.QuadPart/1024;
 }
 else
 {
   Form1->ProgressBar1->Position=TotalBytesTransferred.QuadPart/1024;
   Application->ProcessMessages();
 }
 return cancel?PROGRESS_CANCEL:pause?PROGRESS_STOP:PROGRESS_CONTINUE;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 cancel=pause=0;
 if(CopyFileEx(Edit1->Text.c_str(), Edit2->Text.c_str(), progressfun,0,0,0))
 {
   ShowMessage("Копирование завершено!");
 }
 else
 {
   int lasterr=GetLastError();
   String msg;
   if(lasterr==ERROR_REQUEST_ABORTED)msg=cancel?"Отменено пользователем":"Копирование можно возобновить";
   else msg=SysErrorMessage(lasterr);
   ShowMessage("Копирование файла не выполнено:\n"+msg);
 }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
 pause=1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 cancel=1;       
}
//---------------------------------------------------------------------------


Однако сравнил время копирования файла размером 2 412 146 169 байт с помощью этого алгоритма и с помощью т. коммандера. Разница составиляла от 7 до 10 секунд.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0878 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.