Копирование файла
От: Dan123  
Дата: 06.10.10 15:53
Оценка:
Здравствуйте!
Нужно копировать файл с отображением хода копирования, например в прогрессбаре.
CopyFileEx мне не подходит. Самое простое, что пришло на ум, так это открыть исходный
файл на чтение, файл назначения на запись и побайтно переписать туда данные. А затем
новому файлу присвоить атрибуты, время создания, время последнего изменения и т.д. такие же,
как и у исходного файла. Ниже пример кода. В данном примере нет отображения хода копирования,
поскольку в данном случае реализация отображения прогрессбара не составляет проблем.

Вопрос в другом, могу ли я при таком подходе наступить на какие-нибудь непредвиденные грабли?

Нужно ли при таком подходе после процесса копирования еще раз открыть файлы и сравнить их побайтно,
чтобы убедиться в том, что файлы идентичны?

Я пробовал копировать таким образом скрытые, системные файлы, архивы защищенные паролем. Все работает нормально.
Единственное, хотелось бы, чтобы скорость копирования была побыстрее, но изменение размера буфера на скорость
копирования особо не сказалось.

private void copyFile(string _inputFile, string _outputFile)
{
inputFile = new FileStream(_inputFile, FileMode.Open);
outputFile = new FileStream(string _outputFile, FileMode.Create);
int i = 0;
do
{
byte[] bytes = new byte[1000];
i = inputFile.Read(bbb,0,1000);
if (i != 0)
{
outputFile.Write(bbb, 0, i);
}
} while (i != 0);

inputFile.Close();
outputFile.Close();

// теперь у скопированного файла делаю такие же атрибуты как и у исходного файла.
FileInfo source = new FileInfo(inputFile);
FileInfo destination = new FileInfo(outputFile);
destination.Attributes = source.Attributes;
destination.CreationTime = source.CreationTime;
destination.LastAccessTime = source.LastAccessTime;
destination.LastWriteTime = source.LastWriteTime;
destination.IsReadOnly = source.IsReadOnly;
destination.CreationTimeUtc = source.CreationTimeUtc;
}
Re: Копирование файла
От: _FRED_ Черногория
Дата: 06.10.10 16:04
Оценка:
Здравствуйте, Dan123, Вы писали:

[cs]
D>              byte[] bytes = new byte[1000];
[/cs]

Help will always be given at Hogwarts to those who ask for it.
Re: Копирование файла
От: _FRED_ Черногория
Дата: 06.10.10 16:07
Оценка:
Здравствуйте, Dan123, Вы писали:

D>Я пробовал копировать таким образом скрытые, системные файлы, архивы защищенные паролем. Все работает нормально.

D>Единственное, хотелось бы, чтобы скорость копирования была побыстрее, но изменение размера буфера на скорость
D>копирования особо не сказалось.

Размер буфера надо менять сильно (выше сказал).

Во-вторых, показанное вами копирование, не обижайтесь, но детский сад. Надо из одного файла асинхронно читать (BeginRead), а в другой асинхронно писать (BeginWrite). Это позволит копировать файл практически со скроростью записи (или что там будет медленнее). У вас сейчас скорости чтения и записи суммируются.
Help will always be given at Hogwarts to those who ask for it.
Re: Копирование файла
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.10.10 17:25
Оценка:
Здравствуйте, Dan123, Вы писали:

D>Единственное, хотелось бы, чтобы скорость копирования была побыстрее, но изменение размера буфера на скорость

D>копирования особо не сказалось.

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

Теоретически раза в 2 с небольшим можно ускориться.
Re[2]: Копирование файла
От: Аноним  
Дата: 06.10.10 19:11
Оценка: -1
Здравствуйте, samius, Вы писали:

S>б) используй асинхронные операции с тем что бы писалось пока читается и читается пока пишется (а не последовательно).


S>Теоретически раза в 2 с небольшим можно ускориться.


уже второй раз предлагают использовать параллельное копирование, но никто не учитывает, что файлы копируют в реальной жизни не только с разных физических дисков, но и одного (между логическими). в этом случае мы может ожидать только падения производительности.
Re[2]: Копирование файла
От: Neco  
Дата: 06.10.10 19:25
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR> Надо из одного файла асинхронно читать (BeginRead), а в другой асинхронно писать (BeginWrite). Это позволит копировать файл практически со скроростью записи (или что там будет медленнее). У вас сейчас скорости чтения и записи суммируются.

Ммм...
Наверное, дело вкуса, но я бы сделал просто обёртку на читающим потоком и в обёртке реализовал бы упреждающее (асинхронное) чтение. Это позволит контролировать размер расходуемой памяти и выключать эту функциональность прозрачно для конечного кода. Зачем асинхронно писать я не понял. По-моему, если и то и другое делать асинхронно проблем получите больше, чем преимуществ. У вас есть под рукой пример такой реализации?
всю ночь не ем, весь день не сплю — устаю
Re[3]: Копирование файла
От: Dan123  
Дата: 06.10.10 19:26
Оценка:
А>уже второй раз предлагают использовать параллельное копирование, но никто не учитывает, что файлы копируют в реальной жизни не только с разных физических дисков, но и одного (между логическими). в этом случае мы может ожидать только падения производительности.

Так каким же тогда способом лучше копировать? Я сравнил скорость копирования одного и того же файла размером в 700 мБ в Тotal Commander и приведенном мною коде.
Разница составила 15 сек. В принципе меня это не очень напрягает, но хотелось бы чтобы скорость копирования по крайней мере не уступала тому же Тotal Commander.
Стоит заморачиваться с асинхронным копированием?
Re[4]: Копирование файла
От: Аноним  
Дата: 06.10.10 19:29
Оценка:
Здравствуйте, Dan123, Вы писали:

D>Так каким же тогда способом лучше копировать? Я сравнил скорость копирования одного и того же файла размером в 700 мБ в Тotal Commander и приведенном мною коде.

D>Разница составила 15 сек. В принципе меня это не очень напрягает, но хотелось бы чтобы скорость копирования по крайней мере не уступала тому же Тotal Commander.
D>Стоит заморачиваться с асинхронным копированием?

главный "секрет" быстрого копирования Total COmmander и иже с ним в том, что они перед началом записи резервируют метсо в файловой системе (устанавливают размер выходного файла) — открываете выходной файл, перемещаете указатель на size байт и делаете Truncate, возвращаете указатель в начало и выполняетет копирование. буфер возьмите на пару мегов (уж точно не ГИГОВ как советовали выше — свопитсо будет ваш буфер неистово!)
Re[3]: Копирование файла
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.10.10 19:32
Оценка:
Здравствуйте, Neco, Вы писали:

N>Зачем асинхронно писать я не понял. По-моему, если и то и другое делать асинхронно проблем получите больше, чем преимуществ. У вас есть под рукой пример такой реализации?

У меня есть. Но вот второго диска нет, что бы сравнить.
Re[3]: Копирование файла
От: Neco  
Дата: 06.10.10 19:32
Оценка:
Здравствуйте, Аноним, Вы писали:

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

Могу ошибаться, но по-моему уже давно в ходу технология, которая оптимизирует движения головки — т.е. вероятнее всего скорость не изменится при однопоточном/многопоточном варианте.
Млин, придётся сёдня вечером потестировать — заинтриговал этот вопрос. ))
всю ночь не ем, весь день не сплю — устаю
Re[4]: Копирование файла
От: Аноним  
Дата: 06.10.10 19:35
Оценка: +1
Здравствуйте, Neco, Вы писали:

N>Могу ошибаться, но по-моему уже давно в ходу технология, которая оптимизирует движения головки — т.е. вероятнее всего скорость не изменится при однопоточном/многопоточном варианте.

куда оптимизирует? у вас есть два потока которые вытесняют периодически друг-друга, выполняя чтения-запись с потенциально разных мест жесткого диска. где тут отсутствие перемещения головки?

N>Млин, придётся сёдня вечером потестировать — заинтриговал этот вопрос. ))

вперед
Re[4]: Копирование файла
От: Neco  
Дата: 06.10.10 19:36
Оценка:
Здравствуйте, samius, Вы писали:

N>>Зачем асинхронно писать я не понял. По-моему, если и то и другое делать асинхронно проблем получите больше, чем преимуществ. У вас есть под рукой пример такой реализации?

S>У меня есть. Но вот второго диска нет, что бы сравнить.
чтобы сравнить однопоточный вариант с однопоточным второй диск не нужен. Пример реализации у Фреда я попросил чуть раньше, чем речь зашла о количестве дисков, просто чтобы оценить (на глаз) насколько всё станет сложнее если оба действия выполнять асинхронно.
всю ночь не ем, весь день не сплю — устаю
Re[5]: Копирование файла
От: Dan123  
Дата: 06.10.10 19:37
Оценка:
А>главный "секрет" быстрого копирования Total COmmander и иже с ним в том, что они перед началом записи резервируют метсо в файловой системе (устанавливают размер выходного файла) — открываете выходной файл, перемещаете указатель на size байт и делаете Truncate, возвращаете указатель в начало и выполняетет копирование. буфер возьмите на пару мегов (уж точно не ГИГОВ как советовали выше — свопитсо будет ваш буфер неист


Спасибо! Завтра попробую с этим разобраться.
Re[5]: Копирование файла
От: Neco  
Дата: 06.10.10 19:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>куда оптимизирует? у вас есть два потока которые вытесняют периодически друг-друга, выполняя чтения-запись с потенциально разных мест жесткого диска. где тут отсутствие перемещения головки?

ну собственно на любой машине (особенно сервере) есть куча разных процессов, которые работают с диском вытесняя друг друга (т.е. потоков больше чем два) — вот их работу и призвана оптимизировать эта технология (нет, я не вспомню, как она называется).
всю ночь не ем, весь день не сплю — устаю
Re[5]: Копирование файла
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.10.10 19:49
Оценка:
Здравствуйте, Neco, Вы писали:

N>Здравствуйте, samius, Вы писали:


N>чтобы сравнить однопоточный вариант с однопоточным второй диск не нужен.

Полагаю речь о последовательном vs асинхронном.
Да, сравнил. на 1.3гб файле в пределах одного диска 40 сек +/- секунду в зависимости от запуска к запуску.

N>Пример реализации у Фреда я попросил чуть раньше, чем речь зашла о количестве дисков, просто чтобы оценить (на глаз) насколько всё станет сложнее если оба действия выполнять асинхронно.


конечно, код чуток сложнее.
Re[6]: Копирование файла
От: Neco  
Дата: 06.10.10 19:54
Оценка:
Здравствуйте, samius, Вы писали:

S>конечно, код чуток сложнее.

и вы его не покажете?
всю ночь не ем, весь день не сплю — устаю
Re[7]: Копирование файла
От: samius Япония http://sams-tricks.blogspot.com
Дата: 06.10.10 19:56
Оценка: 24 (4)
Здравствуйте, Neco, Вы писали:

N>Здравствуйте, samius, Вы писали:


S>>конечно, код чуток сложнее.

N>и вы его не покажете?
отнюдь.
Re[3]: Копирование файла
От: _FRED_ Черногория
Дата: 07.10.10 04:24
Оценка: 1 (1) +1
Здравствуйте, Аноним, Вы писали:

S>>б) используй асинхронные операции с тем что бы писалось пока читается и читается пока пишется (а не последовательно).

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

А вы посмотрите на проблему по-другому: во-первых, медленнее работать не будет: в самом худшем случае (который, на современных-то винтах не наступит при нормально работающем оборудовании и драйверах) запросы на чтение\запись выстроятся в одну очередь и получится ровно то, что есть сейчас. Но, во-вторых, когда пользователь прикупит себе SSD, вот там, как на хорошей трассе, разница между спортивной машиной и драндулетом даст знать
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Копирование файла
От: Аноним  
Дата: 07.10.10 04:57
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, Аноним, Вы писали:


_FR>А вы посмотрите на проблему по-другому: во-первых, медленнее работать не будет: в самом худшем случае (который, на современных-то винтах не наступит при нормально работающем оборудовании и драйверах) запросы на чтение\запись выстроятся в одну очередь и получится ровно то, что есть сейчас. Но, во-вторых, когда пользователь прикупит себе SSD, вот там, как на хорошей трассе, разница между спортивной машиной и драндулетом даст знать


как не посмотрю никак не откроется тот прекрасный вид, что написали

вот на выделенное хочу увидеть подтверждение, доказательство, что асинхронные запросы ны выполнение операций с диском (а запись — это достаточно сложная операция, которая не просто делегируется hdd. при записи обновляется куча доп инфы) не вытесняют друг-друг. да и вообще результаты тестов в студию
Re: Копирование файла
От: Sinix  
Дата: 07.10.10 05:06
Оценка: -1
Здравствуйте, Dan123, Вы писали:

D>Здравствуйте!


1. Использовать FileSystem.CopyXXX из VB
2. Если не позволяет религия — подсмотреть рефлектором и скопипастить
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.