Что нового

[Файловая система] Удаление файлов в папке до нужного количества по критерию FileGetTime

ivsatel

Продвинутый
Сообщения
319
Репутация
84
Здравствуйте.

Использую AutoIt 3.3.8.1

Пытаюсь создать функцию, которая должна будет:

  • - Получить список файлов в папке в массив
  • - - Получить массив времени создания файлов для дальнейшего использования как критеря
  • - - - Удалить из папки самые "древние" используя критерий файлы, оставив нужное количество (к примеру 20)

Но думаю такой подход:
Код:
#include <Array.au3>
#include <FileOperations.au3>

Dim $ChekDataFile[1], $FileColList

$FileColList = _FO_FileSearch('k:\Temp\', '*.*', True, 125, 1)


_ArrayDelete($FileColList, 0)

For $i = 1 To UBound($FileColList) - 1
		$t = FileGetTime($FileColList[$i], 0, 1)
		_ArrayAdd($ChekDataFile, $t)
	Next


For $i = 1 To UBound($FileColList) - 20 - 1
	_ArrayDelete($ChekDataFile, 0)
	_ArrayDisplay($ChekDataFile)

	$min = _ArrayMinIndex($ChekDataFile)
	_ArrayDelete($FileColList, $min + $i)
	_ArrayDisplay($FileColList)
Next
Не правильный(
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
ivsatel
Код:
#include <Array.au3>
#include <FileOperations.au3>

Local $iCount = 20
Local $aFileColList = _FO_FileSearch(@TempDir)

Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]

For $i = 1 To $aFileColList[0]
	$aFileColList_2D[$i][0] = $aFileColList[$i]
	$aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next
$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 0, 1, 0, 1)

ReDim $aFileColList_2D[$iCount + 1][2]
$aFileColList_2D[0][0] = $iCount
_ArrayDisplay($aFileColList_2D, 'FileList 2D')


Кстати, Create_list_files может прописаться в конт.меню папки и легко получить список с любыми данными в любой сортировке.
 
Автор
I

ivsatel

Продвинутый
Сообщения
319
Репутация
84
AZJIO
Получилось вот так:
Код:
#include <Array.au3>
#include <FileOperations.au3>

Local $iCount = 20, $z = 0
Local $aFileColList = _FO_FileSearch('k:\Temp\', '*.*', True, 125, 1)

Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]

For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = $aFileColList[$i]
    $aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next

$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)

For $i=1 To UBound($aFileColList_2D, 1) - $iCount - 1

	_ArrayDelete($aFileColList_2D, $iCount)
	;FileDelete($aFileColList_2D[$iCount][0])

Next

$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1

_ArrayDisplay($aFileColList_2D, 'FileList 2D')
 

fedoroff

Новичок
Сообщения
6
Репутация
1
AutoIt v3.3.12
Необходимо решить такую же задачу (пеместить все папки и файлы в корзину), в AutoIt я новичёк.

Скачал файл _ttp://www.autoitscript.com/forum/topic/133224-filesearch-foldersearch и распаковал его в папку C:\Program Files\AutoIt3\Include

После запуска обоих предложенных скриптов получаю сообщение, файлы не удаляются (тэг комментария убрал)
В первом скрипте:
i.imgur.com/nOHqCSc.png
Во втором скрипте:
i.imgur.com/AbNBbHa.png

Что нужно сделать? Спасибо
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
fedoroff
Второй скрипт.

Замените:
Код:
For $i=1 To UBound($aFileColList_2D, 1) - $iCount - 1
    _ArrayDelete($aFileColList_2D, $iCount)
    ;FileDelete($aFileColList_2D[$iCount][0])
Next


На:
Код:
$UB = UBound($aFileColList_2D) - 1
For $i = $UB To $UB - $iCount Step -1
    If $i > 0 Then _
        FileDelete($aFileColList_2D[$i][0])
Next


И уточните свою задачу, ибо тут происходит удаление 20 самых старых файлов из указанной папки.
 

fedoroff

Новичок
Сообщения
6
Репутация
1
Извиняюсь что не уточнил, задача та же что и у автора темы - Удаление файлов в папке до нужного количества по критерию FileGetTime:
- Удалить из папки самые "древние" используя критерий файлы, оставив нужное количество (к примеру 20)
- Дополнительно удалить "древние" папки используя тот же критерий

Видимо я что-то не так делаю, в итоге получился следующий скрипт, но файлы не удаляются:
Какие данные еще необходимо предоставить?

Код:
#include <Array.au3>
#include <FileOperations.au3>

Local $iCount = 20, $z = 0
Local $aFileColList = _FO_FileSearch('f:\MyFolder\', '*.*', True, 125, 1)

Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]

For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = $aFileColList[$i]
    $aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next

$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)

$UB = UBound($aFileColList_2D) - 1
For $i = $UB To $UB - $iCount Step -1
    If $i > 0 Then _
        FileDelete($aFileColList_2D[$i][0])
Next

$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1

_ArrayDisplay($aFileColList_2D, 'FileList 2D')

После выполнения выдает список файлов, файлы не удаляются
i.imgur.com/I1MWgGQ.png

В каталоге f:\MyFolder находятся файлы:
i.imgur.com/oMyZJRx.png

Пробовал менять значения $iCount, значения первого параметра в _FO_FileSearch, заменить FileDelete на FileRecycle
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
если посмотреть на образованный двумерный массив до удаления, то можно заметить, что вторая колонка пустая(у меня так). то есть время последнего изменения не устанавливается.
не пойму почему.
изменил код так
Код:
#include <Array.au3>
 #include <File.au3>

Local $iCount = 20, $z = 0
Local $aFileColList = _FileListToArrayRec('Путь к папке', '*.*', 1, 1, 0,2)
Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]

For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = $aFileColList[$i]
    $aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next
$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)
$UB = UBound($aFileColList_2D) - 1
For $i = $UB To $UB - $iCount Step -1
    If $i > 0 Then _
        FileRecycle($aFileColList_2D[$i][0])
Next
$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1
_ArrayDisplay($aFileColList_2D, 'FileList 2D')
так работает.
вобщем , фантастика. по сути, изменил только функцию поиска файлов.
может AZJIO пояснит?


Добавлено:
Сообщение автоматически объединено:

я нашел в чем проблема. в том, что уже в двумерном массиве пути были с пробелами вначале или в конце . применил функцию удаления этих пробелов и все заработало. весьма странно. может кто пояснить почему так?
Код:
#include <Array.au3>
#include <FileOperations.au3>

Local $iCount = 20, $z = 0
Local $aFileColList = _FO_FileSearch('Путь к папке', '*.*', True, 125, 1)

Local $aFileColList_2D[$aFileColList[0]+1][2] = [[$aFileColList[0]]]

For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = StringStripWS($aFileColList[$i],3)
    $aFileColList_2D[$i][1] = FileGetTime(StringStripWS($aFileColList[$i],3), 0, 1)
Next

$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)

$UB = UBound($aFileColList_2D) - 1
For $i = $UB To $UB - $iCount Step -1
    If $i > 0 Then _
        FileRecycle($aFileColList_2D[$i][0])
Next

$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1

_ArrayDisplay($aFileColList_2D, 'FileList 2D')
 

fedoroff

Новичок
Сообщения
6
Репутация
1
Спасибо, последний скрипт стал удалять файлы в каталоге, указанном в _FO_FileSearch. Но, оказалось, что он не воспринимает "древние" папки. Я считал что по-умолчанию папки тоже принимаются за файлы как в никсах, прошу прощения за недопонимание :(

В связи с этим вопрос:
- Можно ли сделать чтобы AutoIt работал с файлами как с папками и работал только с корневым (указанным в _FO_FileSearch) каталогом без сканирования вложенных файлов в подпапки?

* Например, у нас есть каталог F:\MyFolder c тридцатью папками
* Нужно чтобы после запуска в каталоге F:\MyFolder остались только двадцать из них
Наглядный пример - i.imgur.com/jlyVEXZ.png

Надеюсь не очень сумбурно объяснил, благодарю за понимание.

Или это уже совсем другая задача для отдельной темы?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
тогда только этот вариант. не используя библиотеку FileOperations
Скрипт возвращает только файлы и папки в указанной корневой папке
Код:
#include <Array.au3>
#include <File.au3>

Local $iCount = 20, $z = 0
Local $aFileColList = _FileListToArray('C:\Script', '*.*',0,True)
Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]
For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = $aFileColList[$i]
    $aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next
$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)
$UB = UBound($aFileColList_2D) - 1
For $i = $UB To $UB - $iCount Step -1
    If $i > 0 Then FileRecycle($aFileColList_2D[$i][0])
Next
$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1
_ArrayDisplay($aFileColList_2D, 'FileList 2D')
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
joiner [?]
может AZJIO пояснит?
В новой версии AutoIt изменилось поведение для регулярных выражений. А с учётом поддержки UTF-8 нужно упростить последний флаг локализации. В общем логику надо переписывать, а мне некогда.
 

fedoroff

Новичок
Сообщения
6
Репутация
1
тогда только этот вариант. не используя библиотеку FileOperations
Скрипт возвращает только файлы и папки в указанной корневой папке

joiner
Благодарю, теперь скрипт отлично удаляет и файлы и папки. Но оказалось даже слишком хорошо, после первого запуска оставляет 12 файлов из 33, а после второго - добивает все оставшиеся.
Код:
#include <Array.au3>
#include <File.au3>

Local $iCount = 20, $z = 0
Local $aFileColList = _FileListToArray('F:\MyFolder', '*.*',0,True)
Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]
For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = $aFileColList[$i]
    $aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next
$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)
$UB = UBound($aFileColList_2D) - 1
For $i = $UB To $UB - $iCount Step -1
    If $i > 0 Then FileRecycle($aFileColList_2D[$i][0])
Next
$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1
_ArrayDisplay($aFileColList_2D, 'FileList 2D')

Первый запуск скрипта:
nKDy0el.png
1v1Emqw.png
DRFrkIV.png

Второй запуск скрипта:
DRFrkIV.png
1GA1kkT.png
t1AYovS.png

Что нужно исправить?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
fedoroff [?]
после первого запуска оставляет 12 файлов из 33, а после второго - добивает все оставшиеся.
Попробуйте поменять условие цикла удаления на
Код:
;~ ...
For $i = $iCount + 1 To $UB
;~ ...
И, чтобы не делать лишних действий, можно добавить проверку типа:
Код:
;~ ...
Local $aFileColList = _FileListToArray(@DesktopDir & '\_SearchProxy', '*')
If $aFileColList[0] <= $iCount Then Exit ConsoleWrite('Папок и файлов меньше или равно ' & $iCount & @LF)
;~ ...
 

fedoroff

Новичок
Сообщения
6
Репутация
1
madmasles, премного благодарен, теперь работает.

Большой респект и уважуха всем участникам этой темы за помощь!

Итак, получился следующий готовый скрипт, чтобы таким же новичкам как я можно было сразу его использовать:
Код:
#include <Array.au3>
#include <File.au3>

Local $iCount = 20, $z = 0 ; значение iCount соответствует количеству файлов и папок которые останутся после удаления
Local $aFileColList = _FileListToArray('F:\MyFolder', '*', 0, True) ; значение 'F:\MyFolder' соответствует пути до каталога в котором удаляются "древние" файлы и папки

If $aFileColList[0] <= $iCount Then
   Exit ConsoleWrite('Папок и файлов меньше или равно ' & $iCount & @LF)
EndIf

Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]

For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = $aFileColList[$i]
    $aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next
$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)
$UB = UBound($aFileColList_2D) - 1
For $i = $iCount + 1 To $UB
    If $i > 0 Then FileRecycle($aFileColList_2D[$i][0])
Next
$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1
_ArrayDisplay($aFileColList_2D, 'FileList 2D') ; отобразить список файлов
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
fedoroff,
В цикле удаления проверка на $i > 0 не нужна, достаточно так:
Код:
;~ ...
For $i = $iCount + 1 To $UB
    FileRecycle($aFileColList_2D[$i][0])
Next
;~ ...
 

fedoroff

Новичок
Сообщения
6
Репутация
1
madmasles
Ок, исправил
Код:
#include <Array.au3>
#include <File.au3>

Local $iCount = 20, $z = 0 ; значение iCount соответствует количеству файлов и папок которые останутся после удаления
Local $aFileColList = _FileListToArray('F:\MyFolder', '*', 0, True) ; значение 'F:\MyFolder' соответствует пути до каталога в котором удаляются "древние" файлы и папки

If $aFileColList[0] <= $iCount Then
   Exit ConsoleWrite('Папок и файлов меньше или равно ' & $iCount & @LF)
EndIf

Local $aFileColList_2D[ $aFileColList[0]+1 ][2] = [[ $aFileColList[0] ]]

For $i = 1 To $aFileColList[0]
    $aFileColList_2D[$i][0] = $aFileColList[$i]
    $aFileColList_2D[$i][1] = FileGetTime($aFileColList[$i], 0, 1)
Next
$aFileColList = 0 ; очищаем массив
_ArraySort($aFileColList_2D, 1, 1, 0, 1)
$UB = UBound($aFileColList_2D) - 1
For $i = $iCount + 1 To $UB
    FileRecycle($aFileColList_2D[$i][0])
Next
$aFileColList_2D[0][0] = UBound($aFileColList_2D) - 1
_ArrayDisplay($aFileColList_2D, 'FileList 2D') ; отобразить список файлов
 
Верх