Что нового

[Файловая система] Пробел в начале названия файла

Rjevsky

Новичок
Сообщения
102
Репутация
4
Версия AutoIt: 3.0 и выше

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

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Rjevsky

с попыткой заставить перемещать папку
Код:
#include <Array.au3> ; для _ArrayDisplay
#include <_FileSearch.au3>

$FolderList=_FolderSearch(@ScriptDir&'\Test', ' *', True, 125)
If Not @error Then
	_ArrayDisplay($FolderList, '_FolderSearch')
	For $i = 1 to $FolderList[0]
		$tmp=StringRegExpReplace($FolderList[$i], '^(.*\\)([ ]+)([^\\]*)$', '\1\3')
		If Not @error And @extended And MsgBox(4, 'Сообщение', 'Заменяем?'&@CRLF&$FolderList[$i]&@CRLF&'на'&@CRLF&$tmp)=6 Then DirMove($FolderList[$i], $tmp, 1)
		; $tmp=StringRegExpReplace($FolderList[$i], '^(.*\\)([ ]+[^\\]*)$', '\1')
		; If Not @error And @extended And MsgBox(4, 'Сообщение', 'Заменяем?'&@CRLF&$FolderList[$i])=6 Then DirMove($FolderList[$i], $tmp, 1)
	Next
EndIf

; $test=StringRegExpReplace($test, '\\[ ]+', '\\')

$FileList=_FileSearch(@ScriptDir&'\Test', ' *')
If Not @error Then
	_ArrayDisplay($FileList, '_FileSearch')
	For $i = 1 to $FileList[0]
		$tmp=StringRegExpReplace($FileList[$i], '^(.*\\)([ ]+)([^\\]*)$', '\1\3')
		If Not @error And @extended And MsgBox(4, 'Сообщение', 'Заменяем?'&@CRLF&$FileList[$i])=6 Then FileMove($FileList[$i], $tmp, 9)
	Next
EndIf

_FileSearch здесь
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Rjevsky,
Мой вариант.
Код:
#include <Array.au3>

$sDir = @ScriptDir & '\0'
;пишем:
$sDirTemp = $sDir
For $j = 1 To 10
	For $i = 1 To 10
		If Mod($i, 2) Then
			$hF = FileOpen($sDirTemp & '\   ' & $i & '_test test test.txt', 10);3 пробела
		Else
			$hF = FileOpen($sDirTemp & '\ ' & $i & '_test test test.txt', 10);1 пробел
		EndIf
		FileWrite($hF, $i)
		FileClose($hF)
	Next
	If Mod($j, 2) Then
		$sDirTemp &= '\' & $j;без пробела
	Else
		$sDirTemp &= '\  ' & $j;2 пробела
	EndIf
Next
;ищем и переименовываем папки:
$aDir = _FileSearch($sDir, '*', 2)
If Not @error Then
	_ArrayDisplay($aDir, 'С пробелами папки')
	For $i = $aDir[0] To 1 Step -1
		$sPath = StringRegExpReplace($aDir[$i], '[^\\]*$', '')
		$sDirNew = StringRegExpReplace($aDir[$i], '^.*\\\h*', '')
		DirMove($aDir[$i], $sPath & $sDirNew)
	Next
EndIf
;ищем и переименовываем файлы:
$aFile = _FileSearch($sDir, '*', 1)
If Not @error Then
	_ArrayDisplay($aFile, 'С пробелами файлы')
	For $i = 1 To $aFile[0]
		$sPath = StringRegExpReplace($aFile[$i], '[^\\]*$', '')
		$sFile = StringRegExpReplace($aFile[$i], '^.*\\\h*', '')
		FileMove($aFile[$i], $sPath & $sFile, 1)
	Next
EndIf

$aFile = _FileSearch($sDir, '*')
If Not @error Then
	_ArrayDisplay($aFile, 'Без пробелов')
EndIf

; #FUNCTION# ====================================================================================================
; Name...........:  _FileSearch
; Description....:  Search files and\or folders in a specified path (uses system Dir command)
; Syntax.........:  _FileSearch($sPath [, $sFileMask = "*" [, $iFlag = 0 [, $iSubDir = 1 [, $iSort = 0]]]])
; Parameters.....:  $sPath     - Path to search the file.
;                   $sFileMask - [Optional] Filter to use, default is "*". Search the Autoit3 helpfile for the word "WildCards" For details.
;                   $iFlag     - [Optional] Specifies whether to return files folders or both:
;                                                                                               $iFlag = 0 - Files and folders (default)
;                                                                                               $iFlag = 1 - Only files
;                                                                                               $iFlag = 2 - Only folders
;                   $iSubDir   - [Optional] Specifies whether to search in subfolders or not:
;                                                                                               $iSubDir = 1 - Search in subfolders (default). Returns full pathes.
;                                                                                               $iSubDir = 0 - Search without subfolders (only in $sPath). Returns filenames only.
;                   $iSort     - [Optional] Specifies whether to sort the output list (in alphabetic order) or not (default is 0 - do not sort).
;
; Return values..:  Success    - An array with the following elements:
;                                                                      $aArray[0] = Number of Files\Folders returned
;                                                                      $aArray[1] = 1st File\Folder
;                                                                      $aArray[2] = 2nd File\Folder
;                                                                      $aArray[3] = 3rd File\Folder
;                                                                      $aArray[n] = nth File\Folder
;                   Failure    - 0
;                      @Error:    1 = Path not found or invalid
;                                 2 = No File(s) Found
;
; Author.........:  G.Sandler (MrCreatoR).
; Modified.......:
; Remarks........:  This function uses system Dir command, to speed up the search.
; Related........:
; Link...........:  http://autoit-script.ru/index.php/topic,8266.msg55775
; Example........:
; ===============================================================================================================
Func _FileSearch($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
	Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $sFiles

	If Not StringInStr(FileGetAttrib($sPath), "D") Then
		Return SetError(1, 0, 0)
	EndIf
	If $iSubDir = 1 Then
		$sAttrib &= ' /S'
	EndIf
	If $iSort = 1 Then
		$sAttrib &= ' /O:N'
	EndIf
	Switch $iFlag
		Case 1
			$sAttrib &= ' /A-D'
		Case 2
			$sAttrib &= ' /AD'
		Case Else
			$sAttrib &= ' /A'
	EndSwitch
	$sOut = StringToBinary('0' & @CRLF, 2)
	$sPath = StringRegExpReplace($sPath, '\\+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
	$aMasks = StringSplit($sFileMask, ';')
	For $i = 1 To $aMasks[0]
		If StringStripWS($aMasks[$i], 8) = "" Then
			ContinueLoop
		EndIf
		$sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'
		If $i < $aMasks[0] Then
			$sFiles &= ';'
		EndIf
	Next
	$hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
	While 1
		$sRead = StdoutRead($hDir, False, True)
		If @error Then
			ExitLoop
		EndIf
		If $sRead <> "" Then
			$sOut &= $sRead
		EndIf
	WEnd
	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
	If @error Or UBound($aOut) < 2 Then
		Return SetError(2, 0, 0)
	EndIf
	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc   ;==>_FileSearch
 
Автор
R

Rjevsky

Новичок
Сообщения
102
Репутация
4
madmasles Если на вашем варианте запустить проверку в цикл и натравить на множество папок, то на компьютере начинает постепенно увеличиваться виртуальная память. Хорошо бы исправить...
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Rjevsky [?]
Если на вашем варианте запустить проверку в цикл и натравить на множество папок
Код где? Я же не знаю как Вы это делаете.
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,590
Репутация
341
AZJIO [?]
Я обновил, я ж забыл что можно пробел в маску прописать, так быстрее сработает, а вот с папками какая то засада: заменять не хочет если такая папка уже есть, и флаг не помогает. С файлами проблем нет.
Зачем вообще париться с RegExp'ами? Есть стандартная функция:
Код:
StringStripWS ( "string", 3)

Функция с флагом 3 удалит из названия начальный и конечный пробел :smile:
 
Автор
R

Rjevsky

Новичок
Сообщения
102
Репутация
4
Код:
#include <Array.au3>

$sDir = @ScriptDir & '\0'
;пишем:
While 1
	sleep(200)
;ищем и переименовываем папки:
$aDir = _FileSearch($sDir, '*', 2)
If Not @error Then
;~     _ArrayDisplay($aDir, 'С пробелами папки')
    For $i = $aDir[0] To 1 Step -1
        $sPath = StringRegExpReplace($aDir[$i], '[^\\]*$', '')
        $sDirNew = StringRegExpReplace($aDir[$i], '^.*\\\h*', '')
        DirMove($aDir[$i], $sPath & $sDirNew)
    Next
EndIf
sleep(200)
;ищем и переименовываем файлы:
$aFile = _FileSearch($sDir, '*', 1)
If Not @error Then
;~     _ArrayDisplay($aFile, 'С пробелами файлы')
    For $i = 1 To $aFile[0]
        $sPath = StringRegExpReplace($aFile[$i], '[^\\]*$', '')
        $sFile = StringRegExpReplace($aFile[$i], '^.*\\\h*', '')
        FileMove($aFile[$i], $sPath & $sFile, 1)
    Next
EndIf

;~ $aFile = _FileSearch($sDir, '*')
;~ If Not @error Then
;~     _ArrayDisplay($aFile, 'Без пробелов')
;~ EndIf

WEnd

Func _FileSearch($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
    Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $sFiles

    If Not StringInStr(FileGetAttrib($sPath), "D") Then
        Return SetError(1, 0, 0)
    EndIf
    If $iSubDir = 1 Then
        $sAttrib &= ' /S'
    EndIf
    If $iSort = 1 Then
        $sAttrib &= ' /O:N'
    EndIf
    Switch $iFlag
        Case 1
            $sAttrib &= ' /A-D'
        Case 2
            $sAttrib &= ' /AD'
        Case Else
            $sAttrib &= ' /A'
    EndSwitch
    $sOut = StringToBinary('0' & @CRLF, 2)
    $sPath = StringRegExpReplace($sPath, '\\+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
    $sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
    $aMasks = StringSplit($sFileMask, ';')
    For $i = 1 To $aMasks[0]
        If StringStripWS($aMasks[$i], 8) = "" Then
            ContinueLoop
        EndIf
        $sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'
        If $i < $aMasks[0] Then
            $sFiles &= ';'
        EndIf
    Next
    $hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
    While 1
        $sRead = StdoutRead($hDir, False, True)
        If @error Then
            ExitLoop
        EndIf
        If $sRead <> "" Then
            $sOut &= $sRead
        EndIf
    WEnd
    $aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
    If @error Or UBound($aOut) < 2 Then
        Return SetError(2, 0, 0)
    EndIf
    $aOut[0] = UBound($aOut) - 1
    Return $aOut
EndFunc   ;==>_FileSearch
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Medic84
Пробел то получается не по краям, а в средине. И все пробелы то нельзя удалять, а только то что в начале имени перед символом "\".


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

madmasles
Кстати, та же проблема... если папка целевая существует, то исходную переименовать не получися с помощью DirMove. Нужно придумывать алгоритм переноса внутренностей папки, а перед этим ещё сделать сортировку,чтоб переносить более глубоко вложенные папки, а потом корневые, чтоб найденные пути не испортить.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
AZJIO [?]
а перед этим ещё сделать сортировку,чтоб переносить более глубоко вложенные папки
Сортировать, ИМХО, так можно.
Код:
#include <Array.au3>

$sDir = @DesktopDir
$aReturn = _FileSearch($sDir, ' *', 1)
If @error Then
	MsgBox(16, 'Error ' & @error, '_FileSearch')
	Exit
EndIf
Dim $aTemp[$aReturn[0] +1][2]
For $i = 1 To $aReturn[0]
	$aTemp[$i][0] = $aReturn[$i]
	StringReplace($aReturn[$i], '\', '')
	$aTemp[$i][1] = @extended
Next
_ArraySort($aTemp, 1, 1, 0, 1)
For $i = 1 To $aReturn[0]
	$aReturn[$i] = $aTemp[$i][0]
Next
$aTemp = 0
_ArrayDisplay($aReturn)

;CreatoR; http://autoit-script.ru/index.php/topic,8266.msg55775
;Func _FileSearch
;...
Кстати, функция принимает маску поиска ' *', что ускоряет поиск. Завтра попробую свой вариант переделать.

Rjevsky,
А что делать, если в одной папке есть, например, '\ file.txt' и '\file.txt' или папки такие же?
 
Автор
R

Rjevsky

Новичок
Сообщения
102
Репутация
4
madmasles [?]
А что делать, если в одной папке есть, например, '\ file.txt' и '\file.txt' или папки такие же?
Можно считать, что таких файлов нету, что бы не замарачиваться.
Если замарачиваться, то при наличии файла с тем же названием, но без пробела, на место пробела добавлять случайногенерируемое название Random из, например, 6 знаков.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Rjevsky,
Попробуйте так, у меня работает.
Код:
#include <Array.au3>

Opt('MustDeclareVars', 1)

Global $sDir = @ScriptDir & '\0', $iCountFiles, $iCountDirs

While 1
	$iCountFiles = _RemoveStartSpaceFiles($sDir)
	ConsoleWrite('Files: ' & @error & @TAB & @extended & @TAB & $iCountFiles & @LF)
	Sleep(5000)
	$iCountFiles = _RemoveStartSpaceDirs($sDir)
	ConsoleWrite('Dirs: ' & @error & @TAB & @extended & @TAB & $iCountDirs & @LF)
	Sleep(5000)
WEnd

Func _RemoveStartSpaceDirs($s_SourceDir)
	Local $a_Dirs, $s_Path, $s_Dir, $i_Num, $i_Count, $a_Temp[1]

	$a_Dirs = _FileSearch($sDir, ' *', 2)
	If @error Then Return 0
	ReDim $a_Temp[$a_Dirs[0] + 1][2]
	For $i = 1 To $a_Dirs[0]
		$a_Temp[$i][0] = $a_Dirs[$i]
		StringReplace($a_Dirs[$i], '\', '')
		$a_Temp[$i][1] = @extended
	Next
	_ArraySort($a_Temp, 1, 1, 0, 1)
	For $i = 1 To $a_Dirs[0]
		$a_Dirs[$i] = $a_Temp[$i][0]
	Next
	$a_Temp = 0
	For $i = 1 To $a_Dirs[0]
		$s_Path = StringRegExpReplace($a_Dirs[$i], '\\[^\\]*$', '\\')
		$s_Dir = StringRegExpReplace($a_Dirs[$i], '^.*\\\h+', '')
		$i_Num = 0
		While FileExists($s_Path & $s_Dir)
			$i_Num += 1
			$s_Dir = '(' & $i_Num & ')' & StringRegExpReplace($s_Dir, '^.*\)', '')
		WEnd
		If DirMove($a_Dirs[$i], $s_Path & $s_Dir, 1) Then
			$i_Count += 1
		EndIf
	Next
	Return SetError($a_Dirs[0] - $i_Count, $a_Dirs[0], $i_Count)
EndFunc   ;==>_RemoveStartSpaceDirs

Func _RemoveStartSpaceFiles($s_SourceDir)
	Local $a_Files, $s_Path, $s_File, $i_Num, $i_Count

	$a_Files = _FileSearch($sDir, ' *', 1)
	If @error Then Return 0
	For $i = 1 To $a_Files[0]
		$s_Path = StringRegExpReplace($a_Files[$i], '\\[^\\]*$', '\\')
		$s_File = StringRegExpReplace($a_Files[$i], '^.*\\\h+', '')
		$i_Num = 0
		While FileExists($s_Path & $s_File)
			$i_Num += 1
			$s_File = '(' & $i_Num & ')' & StringRegExpReplace($s_File, '^.*\)', '')
		WEnd
		If FileMove($a_Files[$i], $s_Path & $s_File) Then
			$i_Count += 1
		EndIf
	Next
	Return SetError($a_Files[0] - $i_Count, $a_Files[0], $i_Count)
EndFunc   ;==>_RemoveStartSpaceFiles

Func _FileSearch($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
	;CreatoR; http://autoit-script.ru/index.php/topic,8266.msg55775
	Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $sFiles, $aMasks

	If Not StringInStr(FileGetAttrib($sPath), "D") Then
		Return SetError(1, 0, 0)
	EndIf
	If $iSubDir = 1 Then
		$sAttrib &= ' /S'
	EndIf
	If $iSort = 1 Then
		$sAttrib &= ' /O:N'
	EndIf
	Switch $iFlag
		Case 1
			$sAttrib &= ' /A-D'
		Case 2
			$sAttrib &= ' /AD'
		Case Else
			$sAttrib &= ' /A'
	EndSwitch
	$sOut = StringToBinary('0' & @CRLF, 2)
	$sPath = StringRegExpReplace($sPath, '\\+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
	$aMasks = StringSplit($sFileMask, ';')
	For $i = 1 To $aMasks[0]
		If StringStripWS($aMasks[$i], 8) = "" Then
			ContinueLoop
		EndIf
		$sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'
		If $i < $aMasks[0] Then
			$sFiles &= ';'
		EndIf
	Next
	$hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
	While 1
		$sRead = StdoutRead($hDir, False, True)
		If @error Then
			ExitLoop
		EndIf
		If $sRead <> "" Then
			$sOut &= $sRead
		EndIf
	WEnd
	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
	If @error Or UBound($aOut) < 2 Then
		Return SetError(2, 0, 0)
	EndIf
	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc   ;==>_FileSearch
 
Автор
R

Rjevsky

Новичок
Сообщения
102
Репутация
4
madmasles
Поменял параметры sleep на 1000, что бы быстрее увидеть эффект. Жор виртуальной памяти не прекратился.
На скрине показан момент прекращения работы откомпилированного скрипта после 15 минут работы. Если таклй скрипт поработает несколько дней, то компьютер еле шевелится.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Rjevsky,
Даже не знаю. Добавил во все циклы паузы. Параллельно гонял эти два скрипта почти два часа на старом и слабом ноутбуке, все нормально.
Код:
$sDir = @ScriptDir & '\0'

While 1
	$sDirTemp = $sDir
	For $j = 1 To 10
		For $i = 1 To 10
			$hF = FileOpen($sDirTemp & '\   ' & Random(1, 100, 1) & '_test test test.txt', 10)
			FileWrite($hF, $i)
			FileClose($hF)
			Sleep(10)
		Next
		$sDirTemp &= '\ ' & Random(1, 100, 1)
		Sleep(5000)
	Next
WEnd

Код:
#include <Array.au3>

Opt('MustDeclareVars', 1)

Global $sDir = @ScriptDir & '\0', $iCountFiles, $iCountDirs

While 1
	$iCountFiles = _RemoveStartSpaceFiles($sDir)
	ConsoleWrite('Files: ' & @error & @TAB & @extended & @TAB & $iCountFiles & @LF)
	Sleep(1000)
	$iCountFiles = _RemoveStartSpaceDirs($sDir)
	ConsoleWrite('Dirs: ' & @error & @TAB & @extended & @TAB & $iCountDirs & @LF)
	Sleep(1000)
WEnd

Func _RemoveStartSpaceDirs($s_SourceDir)
	Local $a_Dirs, $s_Path, $s_Dir, $i_Num, $i_Count, $a_Temp[1]

	$a_Dirs = _FileSearch($sDir, ' *', 2)
	If @error Then Return 0
	ReDim $a_Temp[$a_Dirs[0] + 1][2]
	For $i = 1 To $a_Dirs[0]
		$a_Temp[$i][0] = $a_Dirs[$i]
		StringReplace($a_Dirs[$i], '\', '')
		$a_Temp[$i][1] = @extended
	Next
	_ArraySort($a_Temp, 1, 1, 0, 1)
	For $i = 1 To $a_Dirs[0]
		$a_Dirs[$i] = $a_Temp[$i][0]
	Next
	$a_Temp = 0
	For $i = 1 To $a_Dirs[0]
		$s_Path = StringRegExpReplace($a_Dirs[$i], '\\[^\\]*$', '\\')
		$s_Dir = StringRegExpReplace($a_Dirs[$i], '^.*\\\h+', '')
		$i_Num = 0
		While FileExists($s_Path & $s_Dir)
			$i_Num += 1
			$s_Dir = '(' & $i_Num & ')' & StringRegExpReplace($s_Dir, '^.*\)', '')
			Sleep(10)
		WEnd
		If DirMove($a_Dirs[$i], $s_Path & $s_Dir, 1) Then
			$i_Count += 1
		EndIf
		Sleep(10)
	Next
	Return SetError($a_Dirs[0] - $i_Count, $a_Dirs[0], $i_Count)
EndFunc   ;==>_RemoveStartSpaceDirs

Func _RemoveStartSpaceFiles($s_SourceDir)
	Local $a_Files, $s_Path, $s_File, $i_Num, $i_Count

	$a_Files = _FileSearch($sDir, ' *', 1)
	If @error Then Return 0
	For $i = 1 To $a_Files[0]
		$s_Path = StringRegExpReplace($a_Files[$i], '\\[^\\]*$', '\\')
		$s_File = StringRegExpReplace($a_Files[$i], '^.*\\\h+', '')
		$i_Num = 0
		While FileExists($s_Path & $s_File)
			$i_Num += 1
			$s_File = '(' & $i_Num & ')' & StringRegExpReplace($s_File, '^.*\)', '')
			Sleep(10)
		WEnd
		If FileMove($a_Files[$i], $s_Path & $s_File) Then
			$i_Count += 1
		EndIf
		Sleep(10)
	Next
	Return SetError($a_Files[0] - $i_Count, $a_Files[0], $i_Count)
EndFunc   ;==>_RemoveStartSpaceFiles

Func _FileSearch($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
	;CreatoR; http://autoit-script.ru/index.php/topic,8266.msg55775
	Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $sFiles, $aMasks

	If Not StringInStr(FileGetAttrib($sPath), "D") Then
		Return SetError(1, 0, 0)
	EndIf
	If $iSubDir = 1 Then
		$sAttrib &= ' /S'
	EndIf
	If $iSort = 1 Then
		$sAttrib &= ' /O:N'
	EndIf
	Switch $iFlag
		Case 1
			$sAttrib &= ' /A-D'
		Case 2
			$sAttrib &= ' /AD'
		Case Else
			$sAttrib &= ' /A'
	EndSwitch
	$sOut = StringToBinary('0' & @CRLF, 2)
	$sPath = StringRegExpReplace($sPath, '\\+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
	$aMasks = StringSplit($sFileMask, ';')
	For $i = 1 To $aMasks[0]
		If StringStripWS($aMasks[$i], 8) = "" Then
			ContinueLoop
		EndIf
		$sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'
		If $i < $aMasks[0] Then
			$sFiles &= ';'
		EndIf
	Next
	$hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
	While 1
		$sRead = StdoutRead($hDir, False, True)
		If @error Then
			ExitLoop
		EndIf
		If $sRead <> "" Then
			$sOut &= $sRead
		EndIf
		Sleep(10)
	WEnd
	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
	If @error Or UBound($aOut) < 2 Then
		Return SetError(2, 0, 0)
	EndIf
	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc   ;==>_FileSearch
 
Автор
R

Rjevsky

Новичок
Сообщения
102
Репутация
4
madmasles [?]
Даже не знаю. Добавил во все циклы паузы. Параллельно гонял эти два скрипта почти два часа на старом и слабом ноутбуке, все нормально.
запустил ваш скрит - и та же беда. Виртуалка кушается очень быстро. И сам откомпилированный exe раздувается в размерах. Вот мои папки и файлы (упаковано 7zip 4 Мб): http://zalil.ru/32595873
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Rjevsky,
С Вашей папкой.
Код:
#include <File.au3>

$sDir = @ScriptDir & '\0'
While 1
	If @MSEC > 500 Then
		$aList = _FileListToArray($sDir, '*', 1)
		If Not @error Then
			$iRand = Random(1, $aList[0], 1)
			FileMove($sDir & '\' & $aList[$iRand], $sDir & '\  ' & $aList[$iRand], 1)
		EndIf
	Else
		$aList = _FileListToArray($sDir, '*', 2)
		If Not @error Then
			$iRand = Random(1, $aList[0], 1)
			DirMove($sDir & '\' & $aList[$iRand], $sDir & '\  ' & $aList[$iRand], 1)
		EndIf
	EndIf
	Sleep(10000)
WEnd

Код:
#include <Array.au3>
#include <WinAPIEx.au3>;Yashied, http://autoit-script.ru/index.php/topic,47.0.html

Opt('MustDeclareVars', 1)

Global $sDir = @ScriptDir & '\0', $iCountFiles, $iCountDirs

While 1
	$iCountFiles = _RemoveStartSpaceFiles($sDir)
	ConsoleWrite('Files: ' & @error & @TAB & @extended & @TAB & $iCountFiles & @LF)
	Sleep(3000)
	$iCountFiles = _RemoveStartSpaceDirs($sDir)
	ConsoleWrite('Dirs: ' & @error & @TAB & @extended & @TAB & $iCountDirs & @LF)
	_CheckMemory()
	Sleep(3000)
WEnd

Func _CheckMemory()
	Local $iMax = 3145728, _ ;3 Мб
			$aMem = ProcessGetStats()
	ConsoleWrite(Round($aMem[0] / 1024) & ' kb' & @LF)
	If $aMem[0] <= $iMax Then Return
	_WinAPI_EmptyWorkingSet()
EndFunc   ;==>_CheckMemory


Func _RemoveStartSpaceDirs($s_SourceDir)
	Local $a_Dirs, $s_Path, $s_Dir, $i_Num, $i_Count, $a_Temp[1]

	$a_Dirs = _FileSearch($sDir, ' *', 2)
	If @error Then Return 0
	ReDim $a_Temp[$a_Dirs[0] + 1][2]
	For $i = 1 To $a_Dirs[0]
		$a_Temp[$i][0] = $a_Dirs[$i]
		StringReplace($a_Dirs[$i], '\', '')
		$a_Temp[$i][1] = @extended
	Next
	_ArraySort($a_Temp, 1, 1, 0, 1)
	For $i = 1 To $a_Dirs[0]
		$a_Dirs[$i] = $a_Temp[$i][0]
	Next
	$a_Temp = 0
	For $i = 1 To $a_Dirs[0]
		$s_Path = StringRegExpReplace($a_Dirs[$i], '\\[^\\]*$', '\\')
		$s_Dir = StringRegExpReplace($a_Dirs[$i], '^.*\\\h+', '')
		$i_Num = 0
		While FileExists($s_Path & $s_Dir)
			$i_Num += 1
			$s_Dir = '(' & $i_Num & ')' & StringRegExpReplace($s_Dir, '^.*\)', '')
			Sleep(10)
		WEnd
		If DirMove($a_Dirs[$i], $s_Path & $s_Dir, 1) Then
			$i_Count += 1
		EndIf
		Sleep(10)
	Next
	Return SetError($a_Dirs[0] - $i_Count, $a_Dirs[0], $i_Count)
EndFunc   ;==>_RemoveStartSpaceDirs

Func _RemoveStartSpaceFiles($s_SourceDir)
	Local $a_Files, $s_Path, $s_File, $i_Num, $i_Count

	$a_Files = _FileSearch($sDir, ' *', 1)
	If @error Then Return 0
	For $i = 1 To $a_Files[0]
		$s_Path = StringRegExpReplace($a_Files[$i], '\\[^\\]*$', '\\')
		$s_File = StringRegExpReplace($a_Files[$i], '^.*\\\h+', '')
		$i_Num = 0
		While FileExists($s_Path & $s_File)
			$i_Num += 1
			$s_File = '(' & $i_Num & ')' & StringRegExpReplace($s_File, '^.*\)', '')
			Sleep(10)
		WEnd
		If FileMove($a_Files[$i], $s_Path & $s_File) Then
			$i_Count += 1
		EndIf
		Sleep(10)
	Next
	Return SetError($a_Files[0] - $i_Count, $a_Files[0], $i_Count)
EndFunc   ;==>_RemoveStartSpaceFiles

Func _FileSearch($sPath, $sFileMask = "*", $iFlag = 0, $iSubDir = 1, $iSort = 0)
	;CreatoR; http://autoit-script.ru/index.php/topic,8266.msg55775
	Local $sOutBin, $sOut, $aOut, $sRead, $hDir, $sAttrib, $sFiles, $aMasks

	If Not StringInStr(FileGetAttrib($sPath), "D") Then
		Return SetError(1, 0, 0)
	EndIf
	If $iSubDir = 1 Then
		$sAttrib &= ' /S'
	EndIf
	If $iSort = 1 Then
		$sAttrib &= ' /O:N'
	EndIf
	Switch $iFlag
		Case 1
			$sAttrib &= ' /A-D'
		Case 2
			$sAttrib &= ' /AD'
		Case Else
			$sAttrib &= ' /A'
	EndSwitch
	$sOut = StringToBinary('0' & @CRLF, 2)
	$sPath = StringRegExpReplace($sPath, '\\+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, '^;+|;+$', '')
	$sFileMask = StringRegExpReplace($sFileMask, ';{2,}', ';')
	$aMasks = StringSplit($sFileMask, ';')
	For $i = 1 To $aMasks[0]
		If StringStripWS($aMasks[$i], 8) = "" Then
			ContinueLoop
		EndIf
		$sFiles &= '"' & $sPath & '\' & $aMasks[$i] & '"'
		If $i < $aMasks[0] Then
			$sFiles &= ';'
		EndIf
	Next
	$hDir = Run(@ComSpec & ' /U /C DIR ' & $sFiles & ' /B' & $sAttrib, @SystemDir, @SW_HIDE, 6)
	While 1
		$sRead = StdoutRead($hDir, False, True)
		If @error Then
			ExitLoop
		EndIf
		If $sRead <> "" Then
			$sOut &= $sRead
		EndIf
		Sleep(10)
	WEnd
	$aOut = StringRegExp(BinaryToString($sOut, 2), '[^\r\n]+', 3)
	If @error Or UBound($aOut) < 2 Then
		Return SetError(2, 0, 0)
	EndIf
	$aOut[0] = UBound($aOut) - 1
	Return $aOut
EndFunc   ;==>_FileSearch
 
Автор
R

Rjevsky

Новичок
Сообщения
102
Репутация
4
на скрине видно как подросло в какойто момент. Вы дайте поработать часа 3 - увидите сразу рост. Я уже не говорю про сутки. Я на 4-х компьютерах проверял.
Вот 4 часа работы.

Подозреваю, что всё дело в функции _FileSearch. Нарыл вот такую функцию, которая выводит в массив список всех папок и файлов. Осталось переименовать. Помогите плиз.
Код:
Func DirListToArray($sPath, $sRootPath=1)
    $sPath = StringRegExpReplace($sPath, '\\+$', '')
    Local $aRetArray[1], $aSubDirsArr, $sFindNextFile, $sCurrentPath

    Local $sFindFirstFile = FileFindFirstFile($sPath & "\*.*")
    If @error = 1 Then Return SetError(1, 0, -1)

    If $sRootPath = 1 Then
        ReDim $aRetArray[2]
        $aRetArray[1] = $sPath
    EndIf

    While 1
        $sFindNextFile = FileFindNextFile($sFindFirstFile)
        If @error = 1 Then ExitLoop

        $sCurrentPath = $sPath & "\" & $sFindNextFile

;~         If not StringInStr(FileGetAttrib($sCurrentPath), "D") Then
            $aRetArray[0] += 1
            ReDim $aRetArray[$aRetArray[0]+1]
            $aRetArray[$aRetArray[0]] = $sCurrentPath

            $aSubDirsArr = DirListToArray($sCurrentPath, 0)

            If IsArray($aSubDirsArr) Then
                For $i = 1 To $aSubDirsArr[0]
                    $aRetArray[0] += 1
                    ReDim $aRetArray[$aRetArray[0]+1]
                    $aRetArray[$aRetArray[0]] = $aSubDirsArr[$i]
                Next
;~             EndIf
        EndIf
    WEnd

    FileClose($sFindFirstFile)

    Return $aRetArray
EndFunc
 
Верх