Автор Тема: Копируем файлы без "тормозов"  (Прочитано 32420 раз)

0 Пользователей и 2 Гостей просматривают эту тему.

Оффлайн Kaster [?]

  • Бритва, Бритва Оккама
  • Глобальный модератор
  • *
  • Сообщений: 4020
  • Репутация: 622
  • Пол: Мужской
  • Мой Аватар, он лучший самый
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Копируем файлы без "тормозов"
« Ответ #15, Отправлен: Февраль 17, 2011, 20:06:02 »
Kaster  [?]
Цитировать
а папки копировать умеет?

Yashied  [?]
Цитировать
Не умеет. Это тривиальная задача, и каждый может самостоятельно это написать.

[?]
Цитировать
Там уже можно будет копировать не только файлы, но и папки целиком.
:sorcerer: :thumbs_up:
Конференция посвященная AutoIt на jabber.ru - [email protected]
Как попасть на конференцию читаем тут


Русское сообщество AutoIt

Re: Копируем файлы без "тормозов"
« Ответ #15 Отправлен: Февраль 17, 2011, 20:06:02 »

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379

  • Автор темы
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #16, Отправлен: Февраль 18, 2011, 00:58:40 »
Обновил библиотеку до версии 1.3.

Список изменений:
(нажмите для показа/скрытия)

Еще раз напомню, что весь процесс копирования и перемещения файлов происходит с помощью функций CopyFileEx() и MoveFileWithProgress() соответственно. Другими словами, это именно то, что делает сама система, когда вы копируете файлы в Explorer'е. Соответственно и скорость копирования файлов с помощью данной библиотеки соизмерима со скоростью копирования в Windows, а в Windows 7 у меня получается даже быстрее.

:)


Думай, прежде чем говорить.

Оффлайн glax24 [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 14
    • Награды
Re: Копируем файлы без "тормозов"
« Ответ #17, Отправлен: Сентябрь 03, 2011, 19:21:42 »
Yashied
Не подскажите как скомпилировать программу чтобы не требовалась библиотека. Был только один exe.

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379

  • Автор темы
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #18, Отправлен: Сентябрь 04, 2011, 00:16:18 »
Не подскажите как скомпилировать программу чтобы не требовалась библиотека. Был только один exe.

Без Copy.dll никак. Ну, если только FileInstall()...

Русское сообщество AutoIt

Re: Копируем файлы без "тормозов"
« Ответ #18 Отправлен: Сентябрь 04, 2011, 00:16:18 »

Оффлайн glax24 [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 14
    • Награды
Re: Копируем файлы без "тормозов"
« Ответ #19, Отправлен: Сентябрь 04, 2011, 01:11:19 »
Заметил следующую особенность подскажите как исправить.
Сделал копирование в отдельную функцию
Код: AutoIt [Выделить]
Func Copy_Dir($Source, $Destination)
    If $Copy Then
                _Copy_Abort()
            Else
                If (Not $Source) Or (Not $Destination) Then
                    MsgBox(16, '', 'Источник и папки назначения должны быть определены.', 0, $Form1)
                    Return -1
                EndIf
                $Path = $Destination & '\' & StringRegExpReplace($Source, '^.*\\', '')
                If FileExists($Path) Then
                    If MsgBox(52, '', $Destination & ' уже существует.' & @CR & @CR & 'Заменить?', 0, $Form1) <> 6 Then
                        Return -1
                        ;ContinueLoop
                    EndIf
                EndIf
               GUICtrlSetState($Button_Start, $GUI_DISABLE)
               GUICtrlSetData($Label, 'Preparing...')
              _Copy_CopyDir($Source, $Destination)
                $Copy = 1
            EndIf
EndFunc ; ===>Copy_Dir()

а
Код: AutoIt [Выделить]
While 1
;-----copy----
    If $Copy Then
        $State = _Copy_GetState()
        If $State[0] Then
            If $State[0] = -1 Then
                ; Preparing
            Else
                $Data = Round($State[1] / $State[2] * 100)
                If GUICtrlRead($Progress) <> $Data Then
                    GUICtrlSetData($Progress, $Data)
                EndIf
                $Data = StringRegExpReplace($State[6], '^.*\\', '')
                If GUICtrlRead($Label) <> $Data Then
                    GUICtrlSetData($Label, $Data)
                EndIf
            EndIf
        Else
            Switch $State[5]
                Case 0
                    GUICtrlSetData($Progress, 100)
                    MsgBox(64, '', 'Folder was successfully copied.', 0, $Form1)
                Case 1235 ; ERROR_REQUEST_ABORTED
                    MsgBox(16, '', 'Folder copying was aborted.', 0, $Form1)
                Case Else
                    MsgBox(16, '', 'Folder was not copied.' & @CR & @CR & $State[5], 0, $Form1)
            EndSwitch
              GUICtrlSetData($Progress, 0)
            GUICtrlSetData($Label, '')
            GUICtrlSetState($Button_Start, $GUI_ENABLE)
            GUICtrlSetData($Button_Start, 'Старт')
            $Copy = 0
        EndIf
    EndIf
;----end copy-----
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button_Start
Copy_Dir($Source1,$Destination1)
Copy_Dir($Source2,$Destination2)       
EndSwitch
WEnd

При следующей реализации появляется ошибка MsgBox(16, '', 'Folder copying was aborted.', 0, $Form1)
Если по кнопке $Button_Start вызывать только один раз Copy_Dir($Source1,$Destination1) то все работает. А мне надо сразу копировать несколько разных каталогов.

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379

  • Автор темы
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #20, Отправлен: Сентябрь 04, 2011, 01:31:09 »
Можно копировать одновременно до 256 файлов или папок. Для этого есть 256 слотов (от 0 до 255), см. четвертый параметр у функции _Copy_CopyDir(). По умолчанию используется первый слот (0). Для того, чтобы запустить несколько заданий одновременно, нужно чтобы ID у всех заданий были разные (0, 1, 2 и т.д.).

P.S

Функция должна возвращать ошибку 4 (Thread is now being used).

Оффлайн glax24 [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 14
    • Награды
Re: Копируем файлы без "тормозов"
« Ответ #21, Отправлен: Сентябрь 04, 2011, 16:59:23 »
Помогите решить проблемы
1. Содержимое папки 1 скопировать в корень диска
Добавил переменную в функции Copy_Dir
$Pr_Path - 1 - копировать содержимое папки в корень, 0 - копировать саму папку

Код: AutoIt [Выделить]
If $Pr_Path Then
$Path = $Destination
Else
$Path = $Destination & '\' & StringRegExpReplace($Source, '^.*\\', '')
EndIf                
If FileExists($Path) And $Pr_Path = 0 Then
If MsgBox(52, '', $Path & ' already exists.' & @CR & @CR & 'Do you want to replace it?', 0, $Form1) <> 6 Then
Return -1
;ContinueLoop
 EndIf


Можно ли как-то по другому?

2.Выдает ошибку Folder was not copied 5 если у заменяемого файла атрибут только на чтение.
Какой флаг надо поставить чтобы перезаписать все файлы?

3. При данной реализации при копирование процессор загружается на 100%.
Как исправить?
Код: AutoIt [Выделить]
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include "Copy.au3"

Global $Copy = False,$Path,$State,$Data
If Not _Copy_OpenDll() Then
    MsgBox(16, '', 'DLL not found.')
    Exit
EndIf

$Source1 = @ScriptDir&'\na_flesh' ; Надо копировать содержие папки в корень(Копируется сама папка)
$Destination1 = 'G:\'
$Source2 = 'h:\A386'
$Destination2 = 'G:\'

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 295, 287, 345, 175)
$Button_Start = GUICtrlCreateButton("Старт", 72, 96, 121, 33)
$Progress = GUICtrlCreateProgress(0, 152, 289, 25)
$Label = GUICtrlCreateLabel("", 0, 192, 292, 28)
$Label1 = GUICtrlCreateLabel("", 0, 230, 292, 28)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1

    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button_Start
            Start()
EndSwitch
WEnd
Func Start()
    GUICtrlSetData($Label1, 'Func_1')
    Copy_Start($Source1,$Destination1,1)
    GUICtrlSetData($Label1, 'Func_2')
    Copy_Start($Source2,$Destination2,0)
    GUICtrlSetData($Label1, 'Func_End')
EndFunc ; ===>Start()

;$Pr_Path - 1 - копировать содержимое папки в корень, 0 - копировать саму папку
Func Copy_Start($Source, $Destination, $Pr_Path)

$res = Copy_Dir($Source,$Destination,$Pr_Path)
If $res < 0 Then Return -1

While 1
;-----copy----
    If $Copy Then
        $State = _Copy_GetState()
        If $State[0] Then
            If $State[0] = -1 Then
                ; Preparing
            Else
                $Data = Round($State[1] / $State[2] * 100)
                If GUICtrlRead($Progress) <> $Data Then
                    GUICtrlSetData($Progress, $Data)
                EndIf
                $Data = StringRegExpReplace($State[6], '^.*\\', '')
                If GUICtrlRead($Label) <> $Data Then
                    GUICtrlSetData($Label, $Data)
                EndIf
            EndIf
        Else
            Switch $State[5]
                Case 0
                    GUICtrlSetData($Progress, 100)
                    MsgBox(64, '', 'Folder was successfully copied.', 0, $Form1)
                Case 1235 ; ERROR_REQUEST_ABORTED
                    MsgBox(16, '', 'Folder copying was aborted.', 0, $Form1)
                Case Else
                    MsgBox(16, '', 'Folder was not copied.' & @CR & @CR & $State[5], 0, $Form1)
            EndSwitch
            GUICtrlSetState($Button_Start, $GUI_ENABLE)
            GUICtrlSetData($Progress, 0)
            GUICtrlSetData($Label, '')
            GUICtrlSetData($Button_Start, 'Старт')
            $Copy = 0
            ExitLoop
        EndIf
    EndIf
;----end copy-----
WEnd

EndFunc ;===>Copy_Start()

Func Copy_Dir($Source, $Destination,$Pr_Path)

     If $Copy Then
                _Copy_Abort()
            Else
                If (Not $Source) Or (Not $Destination) Then
                    MsgBox(16, '', 'The source and destination folders must be specified.', 0, $Form1)
                    Return -1
                    ;ContinueLoop
                EndIf
                If $Pr_Path Then
                $Path = $Destination
            Else
                $Path = $Destination & '\' & StringRegExpReplace($Source, '^.*\\', '')
            EndIf
                If FileExists($Path) And $Pr_Path = 0 Then
                    If MsgBox(52, '', $Path & ' already exists.' & @CR & @CR & 'Do you want to replace it?', 0, $Form1) <> 6 Then
                        Return -1
                        ;ContinueLoop
                    EndIf
                EndIf
                GUICtrlSetState($Button_Start, $GUI_DISABLE)
                GUICtrlSetData($Button_Start, 'Отменить')
                _Copy_CopyDir($Source, $Path)
                $Copy = 1
            EndIf
Return 1
EndFunc ; ===>Copy_Dir()


Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379

  • Автор темы
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #22, Отправлен: Сентябрь 05, 2011, 03:05:15 »
Если честно, то я мало что понял из вопроса.

Выдает ошибку Folder was not copied 5 если у заменяемого файла атрибут только на чтение.
Какой флаг надо поставить чтобы перезаписать все файлы?

Перед копированием нужно снять атрибут "Только чтение".

При данной реализации при копирование процессор загружается на 100%.
Как исправить?

У меня сейчас стоит Windows 7, и загрузка ~10%, как и в проводнике Windows. В XP, вроде бы, была загрузка тоже под потолок. В любом случае, это системные функции, и как используется процессор зависит только от самой системы. Этот показатель должен быть приблизительно равен оному в проводнике.

P.S

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

Русское сообщество AutoIt

Re: Копируем файлы без "тормозов"
« Ответ #22 Отправлен: Сентябрь 05, 2011, 03:05:15 »

Оффлайн glax24 [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 14
    • Награды
Re: Копируем файлы без "тормозов"
« Ответ #23, Отправлен: Сентябрь 05, 2011, 08:43:04 »
При данной реализации при копирование процессор загружается на 100%.
Как исправить?
Здается мне что я где то напутал, а найти не могу где. Т.к в вашем примере такого эффекта нет.
Код: AutoIt [Выделить]
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include "Copy.au3"

Global $Copy = False,$Path,$State,$Data
If Not _Copy_OpenDll() Then
    MsgBox(16, '', 'DLL not found.')
    Exit
EndIf

$Source1 = @ScriptDir&'\na_flesh' ; Надо копировать содержие папки в корень(Копируется сама папка)
$Destination1 = 'G:\'
$Source2 = 'h:\A386'
$Destination2 = 'G:\'

#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 295, 287, 345, 175)
$Button_Start = GUICtrlCreateButton("Старт", 72, 96, 121, 33)
$Progress = GUICtrlCreateProgress(0, 152, 289, 25)
$Label = GUICtrlCreateLabel("", 0, 192, 292, 28)
$Label1 = GUICtrlCreateLabel("", 0, 230, 292, 28)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1

    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button_Start
            Start()
EndSwitch
WEnd
Func Start()
    GUICtrlSetData($Label1, 'Func_1')
    Copy_Start($Source1,$Destination1,1)
    GUICtrlSetData($Label1, 'Func_2')
    Copy_Start($Source2,$Destination2,0)
    GUICtrlSetData($Label1, 'Func_End')
EndFunc ; ===>Start()

;$Pr_Path - 1 - копировать содержимое папки в корень, 0 - копировать саму папку
Func Copy_Start($Source, $Destination, $Pr_Path)

$res = Copy_Dir($Source,$Destination,$Pr_Path)
If $res < 0 Then Return -1

While 1
;-----copy----
    If $Copy Then
        $State = _Copy_GetState()
        If $State[0] Then
            If $State[0] = -1 Then
                ; Preparing
            Else
                $Data = Round($State[1] / $State[2] * 100)
                If GUICtrlRead($Progress) <> $Data Then
                    GUICtrlSetData($Progress, $Data)
                EndIf
                $Data = StringRegExpReplace($State[6], '^.*\\', '')
                If GUICtrlRead($Label) <> $Data Then
                    GUICtrlSetData($Label, $Data)
                EndIf
            EndIf
        Else
            Switch $State[5]
                Case 0
                    GUICtrlSetData($Progress, 100)
                    MsgBox(64, '', 'Folder was successfully copied.', 0, $Form1)
                Case 1235 ; ERROR_REQUEST_ABORTED
                    MsgBox(16, '', 'Folder copying was aborted.', 0, $Form1)
                Case Else
                    MsgBox(16, '', 'Folder was not copied.' & @CR & @CR & $State[5], 0, $Form1)
            EndSwitch
            GUICtrlSetState($Button_Start, $GUI_ENABLE)
            GUICtrlSetData($Progress, 0)
            GUICtrlSetData($Label, '')
            GUICtrlSetData($Button_Start, 'Старт')
            $Copy = 0
            ExitLoop
        EndIf
    EndIf
;----end copy-----
WEnd

EndFunc ;===>Copy_Start()

Func Copy_Dir($Source, $Destination,$Pr_Path)

     If $Copy Then
                _Copy_Abort()
            Else
                If (Not $Source) Or (Not $Destination) Then
                    MsgBox(16, '', 'The source and destination folders must be specified.', 0, $Form1)
                    Return -1
                    ;ContinueLoop
                EndIf
                If $Pr_Path Then
                $Path = $Destination
            Else
                $Path = $Destination & '\' & StringRegExpReplace($Source, '^.*\\', '')
            EndIf
                If FileExists($Path) And $Pr_Path = 0 Then
                    If MsgBox(52, '', $Path & ' already exists.' & @CR & @CR & 'Do you want to replace it?', 0, $Form1) <> 6 Then
                        Return -1
                        ;ContinueLoop
                    EndIf
                EndIf
                GUICtrlSetState($Button_Start, $GUI_DISABLE)
                GUICtrlSetData($Button_Start, 'Отменить')
                _Copy_CopyDir($Source, $Path)
                $Copy = 1
            EndIf
Return 1
EndFunc ; ===>Copy_Dir()


Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379

  • Автор темы
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #24, Отправлен: Сентябрь 05, 2011, 09:50:32 »
Поставьте в цикле Sleep(1).
« Последнее редактирование: Сентябрь 05, 2011, 10:58:20 от Yashied »

Оффлайн glax24 [?]

  • Новичок
  • *
  • Сообщений: 72
  • Репутация: 14
    • Награды
Re: Копируем файлы без "тормозов"
« Ответ #25, Отправлен: Сентябрь 05, 2011, 14:17:18 »
Yashied
Попробуйте создайте каталог, а в нем файл с атрибутом только на чтение.
При повторном копирование будет ошибка.
(нажмите для показа/скрытия)

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2316
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #26, Отправлен: Сентябрь 05, 2011, 14:45:59 »
glax24  [?]
Цитировать
а в нем файл с атрибутом только на чтение.
При повторном копирование будет ошибка.
Наверное, в этом случае надо собирать файлы из папки в 2-х мерный массив (имя - атрибуты), снимать у файлов атрибуты, копировать, а после копирования восстанавливать атрибуты (если надо).

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379

  • Автор темы
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #27, Отправлен: Сентябрь 05, 2011, 16:53:14 »
Атрибут "Только для чтения" как раз и предназначен для того, чтобы были проблемы при удалении файлов. Вам нужно просто рекурсивно снять атрибуты "Только для чтения" и "Скрытый" у файлов в заменяемой папке и всех ее подпапках. При копировании все атрибуты будут соответствовать исходным файлам.

Оффлайн madmasles [?]

  • Глобальный модератор
  • *
  • Сообщений: 7790
  • Репутация: 2316
  • Пол: Мужской
  • Награды За модерирование форума
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #28, Отправлен: Сентябрь 05, 2011, 17:32:31 »
Yashied,
Чтобы снять определенные атрибуты у файлов и, если нужно, восстановить эти атрибуты после копирования (перемещения), нужно получить имена всех файлов в папке (подпапках). А имея список файлов, ИМХО, проще использовать _Copy_CopyFile().

Оффлайн Yashied [?]

  • AutoIt MVP
  • Глобальный модератор
  • *
  • Сообщений: 5379

  • Автор темы
  • Репутация: 2695
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.x.x
Re: Копируем файлы без "тормозов"
« Ответ #29, Отправлен: Сентябрь 05, 2011, 18:29:15 »
Ладно, не замарачивайтесь, вот новая Copy.dll. Она сама снимает "Read Only" и "Hidden" атрибуты при копировании и перемещении папок. При копировании и перемещении отдельных файлов, как и раньше, вы получите ошибку ERROR_ACCESS_DENIED (5).
« Последнее редактирование: Сентябрь 05, 2011, 19:27:16 от Yashied »

Русское сообщество AutoIt

Re: Копируем файлы без "тормозов"
« Ответ #29 Отправлен: Сентябрь 05, 2011, 18:29:15 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
6 Ответов
12595 Просмотров
Последний ответ Октябрь 07, 2009, 09:36:42
от akoulev
12 Ответов
12442 Просмотров
Последний ответ Декабрь 01, 2012, 02:05:11
от defens
16 Ответов
7262 Просмотров
Последний ответ Октябрь 17, 2010, 02:44:12
от Yashied
2 Ответов
7738 Просмотров
Последний ответ Ноябрь 02, 2010, 11:58:00
от Linaleks
8 Ответов
21254 Просмотров
Последний ответ Февраль 09, 2011, 22:04:08
от Kaster
4 Ответов
5708 Просмотров
Последний ответ Апрель 05, 2011, 01:06:51
от assch
8 Ответов
10573 Просмотров
Последний ответ Апрель 10, 2011, 11:50:11
от madmasles
6 Ответов
5968 Просмотров
Последний ответ Август 05, 2011, 23:10:44
от Yashied
2 Ответов
5554 Просмотров
Последний ответ Октябрь 17, 2011, 20:18:09
от Gorenich
6 Ответов
3964 Просмотров
Последний ответ Июнь 16, 2012, 17:27:05
от rollex