1

Тема: AHK: Архивация файлов

Господа, есть ли способ заархивировать и разархивировать файлы на Win XP и Win 7,8 с помощью AHK, аналогично команде "FileInstall"?

Докидывать в папку скрипта AutoHotkeySC.bin, Unicode 32-bit.bin и Ahk2Exe.exe как-то нехочется.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

2

Re: AHK: Архивация файлов

Непонятно, что именно ты хочешь получить в результате.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: Александр_, 2013-03-25 02:04:42)

Re: AHK: Архивация файлов

Насчёт архивов - в SetupAPI есть поддержка *.CAB, в zipfldr.dll есть интерфейсы для работы с *.zip и конечно gzip поддерживается, без него никуда. Ну и этот странный наборчик .
Я на практике только gzip использовал, для парсинга страниц, а для полноценной архивации проще использовать системный архиватор.

4 (изменено: serzh82saratov, 2013-03-25 03:19:03)

Re: AHK: Архивация файлов

Тут вот ещё про 7z.dll написано

а для полноценной архивации проще использовать системный архиватор.

Требуется для частного случая. Килобайт 100-200 текстовых файлов архивировать и обратно. Архив должен понимать (необязательно) только скрипт.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5

Re: AHK: Архивация файлов

Никакого сжатия и прочего не требуется. Просто чтоб несколько файлов были в одном файле, а не в папке.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

6

Re: AHK: Архивация файлов

Тогда что мешает просто записать несколько файлов в один файл? В начале файла выделить место, где записать смещения и размер каждого файла. Читать и писать файлы АНК умеет.

7

Re: AHK: Архивация файлов

YMP
Думал об этом, но вариант гемморойный.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

8 (изменено: Александр_, 2013-03-25 14:33:39)

Re: AHK: Архивация файлов

serzh82saratov пишет:

YMP
Думал об этом, но вариант гемморойный.

Нормальный вариант, только проще будет писать файлы по мере их обработки в таком формате:

|4 байта, длина имени файла|имя файла|8 байт, длина файла|содержимое файла|

После последнего файла записываем ноль(4 байта), для удобства построения цикла.

9

Re: AHK: Архивация файлов

Это вы не по адресу, я в байтах совсем ничего непонимаю
Буду признателен, если вкратце объясните.

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

имя файла|%StartPos%|%StrLen%|имя файла|%StartPos%|%StrLen%

И ниже содержимое всех файлов.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

10

Re: AHK: Архивация файлов

serzh82saratov пишет:

Это вы не по адресу, я в байтах совсем ничего непонимаю
Буду признателен, если вкратце объясните.

Не представляю что там можно объяснять.

serzh82saratov пишет:

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

имя файла|%StartPos%|%StrLen%|имя файла|%StartPos%|%StrLen%

И ниже содержимое всех файлов.

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

11

Re: AHK: Архивация файлов

Александр_ пишет:

Не представляю что там можно объяснять.

Что значат  4 байта, 8 байт?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

12

Re: AHK: Архивация файлов

4 байта — число типа Int, обозначает длину имени файла. 8 байт — число типа Int64, указывает размер файла.

13

Re: AHK: Архивация файлов

YMP пишет:

4 байта — число типа Int *** 8 байт — число типа Int64 ***

Вот это и непонятно, что означает.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

14

Re: AHK: Архивация файлов

Integer, Integer 64 бита. Integer = целое. Чтение и запись чисел в память — это функции NumGet и NumPut. Слова Int и Int64 используются в них для указания типа числа, т.е. фактически его размера — 32 или 64 бита. Байт = 8 бит.

15

Re: AHK: Архивация файлов

YMP
Спасибо. Вё равно не понял.
Можно на простом примере?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

16

Re: AHK: Архивация файлов

А что именно не поняли-то? Объясните подробнее. Пример чего нужен?

17

Re: AHK: Архивация файлов

Вообще ничего не понял
Пример архивации и разархивации.

Ну вот я писал что хочу делать первой строкой:

имя файла|%StartPos%|%StrLen%|имя файла|%StartPos%|%StrLen%

И потом через парсинг строки, узнавая длинну файла, с помощью функции SubStr выделять текст в переменную, и из неё создавать файл. Хотя параметр "StartPos" излишний видимо в этой схеме. Иначально надо вычислить длинну первой строки с параметром, прибавить 2 на перевод каретки, а дальше оно само.

А вашим методом как это выглядит?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

18

Re: AHK: Архивация файлов

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

Что касается примера, то мне пока не ясно, как вы хотите производить архивацию и разархивацию. Допустим, это будут две функции — как вы планируете их вызывать, какие параметры передавать им? Т.е. опишите нужный вам интерфейс, абстрагируясь пока от внутренней работы функций и от структуры архива. Что должно быть на входе, что на выходе и т.п. Не хотелось бы сочинять то, что вам не нужно.

19 (изменено: serzh82saratov, 2013-03-26 11:06:53)

Re: AHK: Архивация файлов

Архивация:
вход - Несколько выбранных текстовых файлов в папке скрипта.
выход - Один текстовый файл.

Разархивация:
вход - Тот самый один текстовый файл.
выход - Несколько тех самых текстовых файлов в папке скрипта с такими же именами.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

20

Re: AHK: Архивация файлов

Все функции уже не раз применялись:

1. получаем входные данные, создаём выходной файл(функция CreateFile)
2. выбираем файл для "архивации", если таких нет то переходим к пункту 9
3. вычисляем имя файла в архиве по оригинальному имени
4. записываем длину полученного на шаге 3 имени(функция WriteFile)
5. записываем имя файла(без завершающего нуля).
6. находим длину обрабатываемого файла и записываем её в выходной файл.
7. пишем содержимое обрабатываемого файла в выходной файл.
8. переход на шаг 2
9. записываем ноль вместо длины имени файла.
10. освобождаем ресурсы(освобождаем выделенную память, закрываем дескрипторы).

21

Re: AHK: Архивация файлов

Предложение Александра проще, поэтому пример по нему. Для простоты не стал делать проверок на ошибки. Вообще же, значение, возвращаемое FileOpen, надо бы проверять на 0.

files = file1.txt, file2.txt, file3.txt ; Список файлов.
archive = arch.txt                      ; Имя файла архива.

; Вызовы функций

pack(files, archive)
unpack(archive)

; Функции

pack(infiles, archive)      ; Архивация
{
    outfile := FileOpen(archive, "w")           ; Открыть архив на запись.
    Loop, Parse, infiles, `,, %A_Space%         ; Разбор списка файлов.
    {
        infile := FileOpen(A_LoopField, "r")    ; Открыть входной файл на чтение.
        length := infile.Length()               ; Измерить.
        infile.RawRead(data, length)            ; Считать в переменную.
        infile.Close()                          ; Закрыть.

        ; Запись в архив
        outfile.WriteInt(StrLen(A_LoopField))   ; Длина имени файла.
        outfile.Write(A_LoopField)              ; Имя файла.
        outfile.WriteInt(length)                ; Размер файла.
        outfile.RawWrite(data, length)          ; Содержимое файла.
    }
    outfile.WriteInt(0)     ; Конец архива.
    outfile.Close()         ; Закрыть архив.
}

unpack(archive)         ; Разархивация
{
    infile := FileOpen(archive, "r")        ; Открыть архив.
    Loop
    {
        nameLength := infile.ReadInt()      ; Длина имени файла.
        If (nameLength = 0)                 ; Если 0, то конец архива.
            Break
        name := infile.Read(nameLength)     ; Имя вложенного файла.
        bytes := infile.ReadInt()           ; Размер вложенного файла.
        infile.RawRead(data, bytes)         ; Содержимое файла.

        outfile := FileOpen(name, "w")      ; Создать файл.
        outfile.RawWrite(data, bytes)       ; Записать содержимое.
        outfile.Close()                     ; Закрыть.
    }
    infile.Close()      ; Закрыть архив.
}

22 (изменено: Александр_, 2013-03-26 15:46:17)

Re: AHK: Архивация файлов

YMP пишет:
outfile := FileOpen(archive, "w")

здорово, я и не знал что появился нормальный класс для работы с файлами. Ещё может возникнуть проблема при считывании большого файла - может просто не хватить памяти, особенно на 32-битных платформах, где вовсе нельзя адресовать больше 4гб(т.е. можно, но windows этого не делает ), а приложению из них всего 2 достаётся.

23

Re: AHK: Архивация файлов

Александр_
Ну, поскольку

Требуется для частного случая. Килобайт 100-200 текстовых файлов архивировать и обратно.

то проблемы с размером файлов не грозят.

24 (изменено: serzh82saratov, 2013-03-26 16:41:32)

Re: AHK: Архивация файлов

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

Игрался я пару недель назад с FileObject, и могу сказать что не очень оно стабильно работает в целом, и в записи в частности. Хотя может что-то не понял.

FileOpen(FileName, "rw")
File.Write(TestString)
File.Close()

Запись оч. часто не срабатывала.

особенно на 32-битных платформах, где вовсе нельзя адресовать больше 4гб(т.е. можно, но windows этого не делает  ), а приложению из них всего 2 достаётся.

Раньше в командной строке правил на Windows 7 32-бит для игрушки надо было, больше двух гб точно можно:

bcdedit /set increaseuserva 3500

разрешить 3.5 гиг. под приложение.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

25

Re: AHK: Архивация файлов

YMP
Спасибо за пример! Буду курить.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

26

Re: AHK: Архивация файлов

serzh82saratov пишет:

]Раньше в командной строке правил на Windows 7 32-бит для игрушки надо было, больше двух гб точно можно:

bcdedit /set increaseuserva 3500

разрешить 3.5 гиг. под приложение.

Ага и ядру 500 метров оставить? Если драйвер упадёт от нехватки памяти, то ты получишь BSOD и все несохранённые данные испарятся безо всяких предупреждений. И это не говоря уже о том, что нельзя писать программу в расчёте на нестандартную конфигурацию ОС.

27

Re: AHK: Архивация файлов

Александр_
Знаю что нехорошо, но проблем небыло. Правда я 2.5 гига выделял.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

28 (изменено: serzh82saratov, 2013-03-28 08:54:48)

Re: AHK: Архивация файлов

Воспользовался кодом из #21 поста, почему-то файл архива создаётся только из списка файлов, то есть самого содержимого файлов в нём нет.
Файлы указываю так:

SetWorkingDir %A_ScriptDir%
files = EQ-Default.ahk, EQ-Opera.ahk, EQ-Rap.ahk, EQ-Rock.ahk, EQ-S-Rock.ahk, EQ-User.ahk

archive = arch.txt   

больше ничего не менял.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

29

Re: AHK: Архивация файлов

Смотрите, что возвращает FileOpen при открытии этих файлов, и если 0, то смотрите значение переменной A_LastError.

30 (изменено: serzh82saratov, 2013-03-28 10:02:30)

Re: AHK: Архивация файлов

***
 Loop, Parse, infiles, `,, %A_Space%         ; Разбор списка файлов.
    { 
       MsgBox,,FileOpen, %  infile := FileOpen(A_LoopField, "r")    ; Открыть входной файл на чтение.
      MsgBox,,A_LastError, %  A_LastError
        length := infile.Length() 
***

FileOpen - пусто
A_LastError - 0

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

31

Re: AHK: Архивация файлов

Значит, открываются нормально. Идите дальше, проверяйте значение length, результат чтения файла в переменную data.

32

Re: AHK: Архивация файлов

Вообщем незнаю что до этого произошло, но все файлы оказались стёртыми. Сейчас всё работает, спасибо!

   Ещё вопрос по FileObject: Можно ли как-то изменить в файле конкретную строку. Например прочитав с помощью IniRead или FileReadLine строку в переменную, можно её заменить в файле с помощью FileObject? То что можно переписать весь файл с помощью FileAppend или FileMove само собой мне понятно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

33

Re: AHK: Архивация файлов

Если строки равны по длине, то можно и заменить (если знаете её смещение). А если не равны, то следующий текст сдвигать надо, так что по-любому остаток файла переписывать. В ini-файле с помощью IniWrite можно заменить.