Что нового

[Данные, строки] Сравнение файлов по размеру и чтение секций из INI

AtoS

Новичок
Сообщения
57
Репутация
2
Доброго времени суток! Подскажите пожалуйста, существует ли функция сравнения файлов по размеру в autoit?
Также есть вопрос по чтению данных из раздела INI. Есть некий INI-файл следующего вида:
[название раздела]
секция = файл1.txt
секция = file2.exe
....
секция = file126.exe

считать весь список поочереди, учитывая то, что название секции одинаковое?(количество строк всегда разное)
 

XM

Знающий
Сообщения
70
Репутация
8
AtoS сказал(а):
...Подскажите пожалуйста, существует ли функция сравнения файлов по размеру в autoit?

#include <File.au3>

$file1 = @ScriptDir & 'file1.txt'
$file2 = @ScriptDir & 'file2.txt'
$iSize1 = FileGetSize($file1)
$iSize2 = FileGetSize($file2)
If $iSize1 > $iSize2 Then
MsgBox(0, '', 'Файл ' & $iSize1 & ' больше чем ' & $iSize2)
ElseIf $iSize1 = $iSize2 Then
MsgBox(0, '', 'Размер файлов одинаков')
ElseIf $iSize1 < $iSize2 Then
MsgBox(0, '', 'Файл ' & $iSize2 & ' больше чем ' & $iSize1)
EndIf



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

AtoS сказал(а):
Также есть вопрос по чтению данных из раздела INI. Есть некий INI-файл следующего вида:
[название раздела]
секция = файл1.txt
секция = file2.exe
....
секция = file126.exe

считать весь список поочереди, учитывая то, что название секции одинаковое?(количество строк всегда разное)

См. IniReadSection()
 

madmasles

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

$aSection = IniReadSection(@ScriptDir & "\MyINI.ini", "название раздела")
If @error Then Exit
_ArrayDisplay($aSection)
MsgBox(0, "", Round(FileGetSize("MyINI.ini") / 1024, 2) & " кб.")
 
Автор
A

AtoS

Новичок
Сообщения
57
Репутация
2
vendor сказал(а):
AtoS сказал(а):
...Подскажите пожалуйста, существует ли функция сравнения файлов по размеру в autoit?
Смотри FileGetSize() в справке


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

AtoS сказал(а):
Также есть вопрос по чтению данных из раздела INI. Есть некий INI-файл следующего вида:
[название раздела]
секция = файл1.txt
секция = file2.exe
....
секция = file126.exe

считать весь список поочереди, учитывая то, что название секции одинаковое?(количество строк всегда разное)

INIReadSection в справке.



Код:
FileGetSize()
возвращает размер файла, а
Код:
INIReadSection
в свою очередь, как я понимаю, возвращаетт пару - секция = ключ
В моем же случае требуется сравнить размер эталонного файла со всеми остальными в определенных директориях и записать в текстовый файл в определенном формате. Затык заключается в формировании списка файлов:
Код:
$FileList=_FileListToArray($dir_etalon,"*.*")
If @Error=1 Then
	MsgBox (0,"","No Folders Found.")
	Exit
EndIf
If @Error=4 Then
	MsgBox (0,"","No Files Found.")
	Exit
EndIf
$sArray = _ArrayToString($FileList)
IniWriteSection ( $file_buff, "ETALON", "replace = "&$sArray)
$file_rep = IniRead($file_buff,"ETALON", "replace","default")
$replace = StringReplace($file_rep, "|", @CRLF&"File =")
IniWriteSection($file_buff2, "ETALON", $replace)

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

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
AtoS
Записать в ini-файл сведения о размере файлов у меня получилось так:
Код:
#include <File.au3>

$dir_etalon = @ScriptDir
$aFileList = _FileListToArray($dir_etalon, "*.*", 1)
If @error = 4 Then Exit
Dim $aFileSize[UBound($aFileList)][2]
$aFileSize[0][0] = UBound($aFileList) - 1
For $i = 1 To UBound($aFileList) - 1
	$aFileSize[$i][0] = $aFileList[$i]
	$aFileSize[$i][1] = FileGetSize(@ScriptDir & "\" & $aFileList[$i])
Next
IniWriteSection(@ScriptDir & "\MyIniFile.ini", $dir_etalon, $aFileSize, 1)

А при проверке надо еще учесть, что количество файлов может увеличиться или уменьшиться.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
AtoS
1. в твоем примере есть понятийная ошибка, которая в дальнейшем может привести к ошибке уже настоящей. а именно, по негласному соглашению о формате ini-файла

[название раздела] - это на самом деле название секции или просто секция;
секция=файл1.txt на самом деле это пара ключ=значение.

2. по тому же соглашению, в ини файле не может быть разных ключей с одинаковыми именами, даже если их значения тоже совпадают. ini-файлы будучи обычными текстовыми файлами накладывают ряд ограничений на их обработку различными встроенными в многие редакторы парсерами. поэтому твой файл я бы переделал так
Код:
[название секции]
ключ1 = файл1.txt
ключ2 = file2.exe
....
ключ126 = file126.exe
 
Автор
A

AtoS

Новичок
Сообщения
57
Репутация
2
Kaster сказал(а):
AtoS
1. в твоем примере есть понятийная ошибка, которая в дальнейшем может привести к ошибке уже настоящей. а именно, по негласному соглашению о формате ini-файла

[название раздела] - это на самом деле название секции или просто секция;
секция=файл1.txt на самом деле это пара ключ=значение.

2. по тому же соглашению, в ини файле не может быть разных ключей с одинаковыми именами, даже если их значения тоже совпадают. ini-файлы будучи обычными текстовыми файлами накладывают ряд ограничений на их обработку различными встроенными в многие редакторы парсерами. поэтому твой файл я бы переделал так
Код:
[название секции]
ключ1 = файл1.txt
ключ2 = file2.exe
....
ключ126 = file126.exe
а как получить список файлов и из этого списка сформировать:
Код:
[название секции]
ключ1 = файл1.txt
ключ2 = file2.exe
....
ключ126 = file126.exe

у меня получилось только:
Код:
[название секции]
ключ = файл1.txt
ключ = file2.exe
....
ключ = file126.exe
При этом количество файлов в эталонном каталоге неизвестно и всегда разное количество каталогов для сверки
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
мне сложно тебе что-либо советовать видя только твой результат. дай хотя бы намек на то, как ты это делаешь. а то
у меня получилось только:
тяжело поддается анализу на предмет совершенствования
 
Автор
A

AtoS

Новичок
Сообщения
57
Репутация
2
Kaster сказал(а):
мне сложно тебе что-либо советовать видя только твой результат. дай хотя бы намек на то, как ты это делаешь. а то
у меня получилось только:
тяжело поддается анализу на предмет совершенствования
Вот моя головная боль - маленький скрипт который формирует эталонный список, проверяет размер файла эталона и других файлов в требуемых директориях а затем по шаблону вываливает мне его в csv для дальнейшей обработки в Excel'е:
Код:
#include <File.au3>
#Include <Array.au3>

$path = "Z:"
$Dir1 = "Dir1"
$dir_etalon = "V:\ETALON\diretalon"
$sFile = "musor.csv"
$file_buff = "test.ini"
$file_buff2 = "test2.ini"
$i = 1


;======================================================
;===		Формирование файлов для сверки			===
;======================================================
$FileList=_FileListToArray($dir_etalon,"*.*")
If @Error=1 Then
	MsgBox (0,"","No Folders Found.")
	Exit
EndIf
If @Error=4 Then
	MsgBox (0,"","No Files Found.")
	Exit
EndIf
$sArray = _ArrayToString($FileList)
IniWriteSection ( $file_buff, "ETALON", "replace = "&$sArray)
$file_rep = IniRead($file_buff,"ETALON", "replace","default")
$replace = StringReplace($file_rep, "|", @CRLF&"File =")
IniWriteSection($file_buff2, "ETALON", $replace)

;======================================================
;===Получение данных из директории Эталонной сборки!===
;======================================================
$etalon_file = IniRead($file_buff2,"ETALON", "File","default")
$etalon_size = FileGetSize($dir_etalon&"\"&$etalon_file)

;======================================================
;===		Получение данных о кассовой сборке		===
;======================================================
FileWrite ( $sFile," ;ETALON")

$file = IniReadSection($file_buff2,"ETALON");, "File","default")
$aPath = _FileListToArray($path, "*", 2)
	For $i = 1 To UBound($aPath) - 1
		If FileExists($path & "\" & $aPath[$i] & "\" & $dir1 & "\" & $file[$i][1]) Then
			$nonetalon_size = FileGetSize($path & "\" & $aPath[$i] & "\" & $dir1 & "\"& $file)
			$cassa_name = FileWrite ( $sFile,";"&$aPath[$i])
		EndIf
	Next
	FileWrite ( $sFile,@CRLF)
	FileWrite ( $sFile,$file&";"&$etalon_size)
	For $i = 1 To UBound($aPath) - 1
		If FileExists($path & "\" & $aPath[$i] & "\" & $dir1 & "\" & $file[$i][1]) Then
			$nonetalon_size = FileGetSize($path & "\" & $aPath[$i] & "\" & $dir1 & "\"& $file)
			FileWrite ( $sFile,";"&$nonetalon_size)
		EndIf
	Next

Весь затык в том, что обрабатывает он мне только только 1 файл из списка, а не все.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
AtoS [?]
обрабатывает он мне только только 1 файл из списка

Kaster [?]
ni-файлы будучи обычными текстовыми файлами накладывают ряд ограничений на их обработку различными встроенными в многие редакторы парсерами

это типа вопрос-ответ

а теперь по существу
Мои рекомендации. пользуйся для записи не IniWriteSection, а просто IniWrite но в цикле. и дай значение ключам - уникальное! это важно. например можешь к каждому ключу добавлять индекс от обрабатываемого массива. к примеру, имеется сколько-то элементов массива которые нужно занести в ini. вот как это сделал бы я
Код:
Dim $a[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
$sINI = @ScriptDir & '\test.ini'
For $i = 1 to UBound($a) - 1
	IniWrite($sINI, 'My Test Section', 'key' & $i, $a[$i])
Next
ShellExecute($sINI)
 

XM

Знающий
Сообщения
70
Репутация
8
В моем же случае требуется сравнить размер эталонного файла со всеми остальными в определенных директориях и записать в текстовый файл в определенном формате. Затык заключается в формировании списка файлов:...
где формируется инишник с одинаковым названием разделов. При этом при считывании данных считывается только первый ключ, а остальные нет.
Вобщем все еще сводиться к созданию сводной информации по проверенным файлам. Не могу одно сделать - считать название файлов из инишника.

Судя по всему, вы не совсем понимаете смысл/действие INI- файлов.
Из условия задачи я понял следующее:
Имеется эталонный файл с именем File1. Так же имеются подобные файлы (File2, File3...), которые разбросаны по разным директориям/дискам и т.п.
Требуется сравнить эти файлы с эталонным, причем записать различия в INI-файл.
Если я правильно понял задачу, то:
- по каким критериям сравнивать файлы? (по размеру, содержимому или и то и др.)
- какую информацию следует заносить в INI-файл?
- какую функцию INI- файл должен выполнять? (хранить базу данных изменений файлов, хранить пути их нахождения или что то еще...)
 

XM

Знающий
Сообщения
70
Репутация
8
Kaster сказал(а):
Мои рекомендации. пользуйся для записи не IniWriteSection, а просто IniWrite но в цикле. и дай значение ключам - уникальное! это важно. например можешь к каждому ключу добавлять индекс от обрабатываемого массива. к примеру, имеется сколько-то элементов массива которые нужно занести в ini. вот как это сделал бы я
Код:
Dim $a[10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
$sINI = @ScriptDir & '\test.ini'
For $i = 1 to UBound($a) - 1
	IniWrite($sINI, 'My Test Section', 'key' & $i, $a[$i])
Next
ShellExecute($sINI)
ЭЭэй! Кастер! При всем уважении, предложенный Вами вариант немного смахивает на обычный "автомат", лишенный всякой смысловой нагрузки... В последствии, однако, трудновато будет извлечь необходимую инфу "ключ-значение" из подобного ini-файла...
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
vendor [?]
В последствии, однако, трудновато будет извлечь необходимую инфу "ключ-значение" из подобного ini-файла
не труднее чем всегда
 

XM

Знающий
Сообщения
70
Репутация
8
Kaster сказал(а):
не труднее чем всегда
Согласен. Но для автора темы.... Впрочем, когда то мы так начинали...


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

AtoS сказал(а):
....маленький скрипт....

Потренеруйся пока вот на этом...
Код:
#include <File.au3>
#include <Array.au3>

Global Const $sIniFile = @ScriptDir & '\Difference.ini'
Global Const $sPath1 = @ScriptDir & '\Directory_1'
Global Const $sPath2 = @ScriptDir & '\Directory_2'
Global Const $sPath3 = @ScriptDir & '\Directory_3'
Global Const $sOutFile = @ScriptDir & '\OutFile.txt'

DirCreate($sPath1)
DirCreate($sPath2)
DirCreate($sPath3)
For $i = 1 To 1000
	$rnd = Random(1, 1000)
	FileWrite($sPath1 & '\file_standard.txt', $rnd & @CRLF)
	FileWrite($sPath2 & '\file_1.txt', $rnd & @CRLF & $rnd & @CRLF)
	FileWrite($sPath2 & '\file_2.txt', $rnd & @CRLF & $rnd & @CRLF & $rnd & @CRLF)
	FileWrite($sPath3 & '\file_3.txt', $rnd & @CRLF & $rnd & @CRLF & $rnd & @CRLF & $rnd & @CRLF)
	FileWrite($sPath3 & '\file_4.txt', $rnd & @CRLF & $rnd & @CRLF & $rnd & @CRLF & $rnd & @CRLF & $rnd & @CRLF)
Next
IniWrite($sIniFile, 'standard', 'Эталон', FileGetSize($sPath1 & '\file_standard.txt') & ' байт')

$aFileListPath_2 = _FileListToArray($sPath2)
	For $i = 1 To UBound($aFileListPath_2) - 1
		$size = FileGetSize($sPath2 & '\' & $aFileListPath_2[$i])
		IniWrite($sIniFile, 'Path 2', $aFileListPath_2[$i], $size & ' байт')
	Next
$aFileListPath_3 = _FileListToArray($sPath3)
	For $i = 1 To UBound($aFileListPath_2) - 1
		$size = FileGetSize($sPath3 & '\' & $aFileListPath_3[$i])
		IniWrite($sIniFile, 'Path 3', $aFileListPath_3[$i], $size & ' байт')
	Next
$aReadSection = IniReadSectionNames($sIniFile)
For $j = 1 To UBound($aReadSection) - 1
	$aKeyVol = IniReadSection($sIniFile, $aReadSection[$j])
	_ArrayDisplay($aKeyVol, $aReadSection[$j])
Next

Дальше лень было писать, да и спать хочеться...
Удачи!
 
Автор
A

AtoS

Новичок
Сообщения
57
Репутация
2
vendor сказал(а):
В моем же случае требуется сравнить размер эталонного файла со всеми остальными в определенных директориях и записать в текстовый файл в определенном формате. Затык заключается в формировании списка файлов:...
где формируется инишник с одинаковым названием разделов. При этом при считывании данных считывается только первый ключ, а остальные нет.
Вобщем все еще сводиться к созданию сводной информации по проверенным файлам. Не могу одно сделать - считать название файлов из инишника.

Судя по всему, вы не совсем понимаете смысл/действие INI- файлов.
Из условия задачи я понял следующее:
Имеется эталонный файл с именем File1. Так же имеются подобные файлы (File2, File3...), которые разбросаны по разным директориям/дискам и т.п.
Требуется сравнить эти файлы с эталонным, причем записать различия в INI-файл.
Если я правильно понял задачу, то:
- по каким критериям сравнивать файлы? (по размеру, содержимому или и то и др.)
- какую информацию следует заносить в INI-файл?
- какую функцию INI- файл должен выполнять? (хранить базу данных изменений файлов, хранить пути их нахождения или что то еще...)
Не совсем так... Имеется эталонный каталог в котором лежат эталонные файлы(могут добавляться/удаляться файлы, поэтому заранее точный список файлов неизвестен). Каждый эталонный файл нужно сравнить по размеру с аналогичным в определенных директориях(количество директорий всегда разное и у них меняется номер(например, cassa622\files\, cassa765\files и т.д.). Далее эти данные консолидируются в текстовом файле для дальнейшей обработки в Экселе:
Название файла Эталонный размер cassa622 Cassa765 Cassa875
file1.txt 765 765 765 768
...
File157.txt 115200 115200 110200 115200

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

XM

Знающий
Сообщения
70
Репутация
8
А обязательно ли использовать INI?
Я предлагаю отправлять данные сразу в Excel:

Допустим, структура каталогов имеет вид:

Код:
Standard:
   |-file1.txt
   |-file2.txt
   |-* * *
   |-fileN.txt

cassa622:
   |-file1.txt
   |-file2.txt
   |-* * *
   |-fileN.txt

* * *

cassaNNN:
   |-file1.txt
   |-file2.txt
   |-* * *
   |-fileN.txt

и каталоги CassaNNN... находятся в одной директории, тогда:

Код:
#include <File.au3>
#include <Array.au3>
#include <Excel.au3>
#include <Array.au3> ; Temporary

Global $sSTDCatalog = @ScriptDir & '\Standard' ; Здесь лежат "эталонные" файлы
Global $sFilesCatalog = @ScriptDir & '\Files' ; Здесь находятся каталоги с файлами "CassaNN"
Global $oExcel
Global $aDataSTD[1][2] ; Объявляем массив в который будут добавлены названия и размеры "стандартных" файлов
$aDataSTD[0][0] = 'Название файла'
$aDataSTD[0][1] = 'Эталонный размер'
$aFileListSTD = _FileListToArray($sSTDCatalog, '*.txt', 1) ; Получаем список файлов в  STD-каталоге
$count = UBound($aFileListSTD) - 1
ReDim $aDataSTD[$count + 1][2] ; Увеличим размерность массива на количество файлов в каталоге

For $i = 1 To $count
	$sizeSTD = FileGetSize($sSTDCatalog & '\' & $aFileListSTD[$i])
	$aDataSTD[$i][0] = $aFileListSTD[$i]
	$aDataSTD[$i][1] = $sizeSTD & ' byte'
Next
;_ArrayDisplay($aDataSTD)

Global $aFileListInCat, $sizeCat
Global $aCatList = _FileListToArray($sFilesCatalog, '*', 2) ; Получаем список каталогов "CassaNN"
$num = UBound($aCatList) - 1
Dim $aCatalog[$num + 1][2] ; Объявим вспомогательный массив с именами каталогов, где [0][0]-элемент содержит кол-во каталогов
$oExcel = _ExcelBookNew()
For $i = 0 To $num
	$aCatalog[$i][0] = $aCatList[$i] ; Заполнение массива
	_ExcelWriteCell($oExcel, $aCatList[$i], 1, $i + 3)
Next
;_ArrayDisplay($aCatalog)

Global $iColsStart = 4
Global $iFileSize ; Переменная - размер файла
Global $aFileListInCat ; Переменная(массив), где [0]-элемент содержит кол-во файлов в каталоге
For $i = 1 To $aCatalog[0][0] ; Крутим цикл столько раз, сколько элементов в массиве $aCatalog
	$aFileListInCat = _FileListToArray($sFilesCatalog & '\' & $aCatalog[$i][0], '*.txt', 1)
	;If @error Then ContinueLoop
	If @error Then
		$aCatalog[$i][1] = 0
	Else
		$aCatalog[$i][1] = $aFileListInCat[0]
	EndIf
	For $j = 1 To $aCatalog[$i][1] ; Крутим цикл столько раз, сколько файлов в текущем каталоге
		$iFileSize = FileGetSize($sFilesCatalog & '\' & $aCatalog[$i][0] & '\' & $aFileListInCat[$j])
		;ConsoleWrite($sFilesCatalog & '\' & $aCatalog[$i][0] & '\' & $aFileListInCat[$j] & ' : ' & $iFileSize & ' byte' & @CRLF)
		_ExcelWriteCell($oExcel, $iFileSize & ' byte', $j + 1, $iColsStart) ; Записываем размеры файлов, начиная с 4-го столбца Excel-файла
	Next
	$iColsStart += 1 ; Переходим на след. столбец Excel-файла
Next
_ExcelWriteSheetFromArray($oExcel, $aDataSTD, 1, 1, 0, 0) ; Записываем размеры "стандартных" файлов
_ExcelColumnDelete($oExcel, 3) ; Удаляем служебный столбец (лишний)
_ExcelFontSetProperties($oExcel, 1, 1, 1, $aCatalog[0][0] + 2, True, False, False) ; Шрифт 1-й строки
_ExcelBookSaveAs($oExcel, @ScriptDir & '\Cassa.xls', 'xls', 0, 1) ; Сохраняем файл


Проект прикрепил (в архиве).
Все что в архиве распаковать в любое место, запустить скрипт и вуаля!
Осталось лишь изменить пути в скрипте на свои, вообщем "заточить" под себя.
 
Автор
A

AtoS

Новичок
Сообщения
57
Репутация
2
Незаменимый пример, примного благодарен vendor и другим участникам форума за помощь в решении этой задачи. Но у меня есть еще один вопрос, как сделать так, чтобы размер проверялся в каталогах CassaNNN только тех файлов, которые присутствуют в папке эталон?(т.к. помимо них в каталоге присутствуют и другие файлы)
 

XM

Знающий
Сообщения
70
Репутация
8
AtoS сказал(а):
... как сделать так, чтобы размер проверялся в каталогах CassaNNN только тех файлов, которые присутствуют в папке эталон?(т.к. помимо них в каталоге присутствуют и другие файлы)

Ах, да, этого я не учел. ОК, сделаю как будет время...
 
Верх