https://youtu.be/eeaVPyb5d2M
Возвращает строки текстового файла, по одной строке (работает быстрее, чем FileReadLine).
Loop, Read, InputFile [, OutputFile]
Параметры
Read |
Этот параметр должен задаваться как слово READ. |
InputFile |
Имя файла, чьё содержимое будет читаться циклом. Если абсолютный путь не задан, файл ищется в папке, указанной в переменной A_WorkingDir. Поддерживаются форматы Windows и Unix, т.е. строки файла могут оканчиваться как возвратом каретки с переводом строки (`r`n), так и одним переводом строки (`n). |
OutputFile |
(Необязателен). Имя файла, который нужно держать открытым, пока работает цикл. Если абсолютный путь не задан, считается, что файл находится в папке, указанной в переменной A_WorkingDir.
В теле цикла используйте команду FileAppend только с одним параметром (текст, который нужно записать), чтобы запись шла в этот файл. Добавление текста в файл таким способом происходит быстрее, чем когда FileAppend используется в режиме с двумя параметрами, так как файл не нужно закрывать и снова открывать при каждой операции. Не забывайте ставить после текста перевод строки (`n), если это желательно.
Этот файл не открывается, если в него ничего не пишется. Это случается, если цикл не выполняется ни разу или если он ни разу не использует команду FileAppend.
Двоичный режим: чтобы текст добавлялся в файл в двоичном, а не в текстовом режиме, поставьте звёздочку перед именем файла. Это приведёт к тому, что каждый символ перевода строки (`n) будет записан как одиночный перевод строки (LF), а не как стандартное для Windows сочетание возврата каретки и перевода строки (CR+LF). Пример: *C:\My Unix File.txt. Даже если звёздочка отсутствует, двоичный режим будет включён автоматически, если при первом использовании FileAppend в цикле записываемый текст будет содержать пары символов возврата каретки и перевода строки (`r`n).
Стандартный выходной поток (stdout): если задать OutputFile как звёздочку (*), то текст, записываемый при помощи FileAppend, будет посылаться в стандартный выходной поток (stdout). Хотя такой вывод может быть перенаправлен в файл, передан по конвейеру в другую программу или перехвачен некоторыми текстовыми редакторами (см. описание директивы #ErrorStdOut), он не будет виден в окне командной строки, откуда был запущен скрипт. Подробности смотрите в описании команды FileAppend.
Экранирование запятых: в отличие от последнего параметра большинства других команд, запятые в OutputFile должны экранироваться (`,). |
Цикл чтения файла полезен в случаях, когда вы хотите обработать каждую строку текстового файла по очереди. Он работает быстрее, чем команда FileReadLine, потому что: 1) файл может оставаться открытым в течение всей операции; и 2) нет необходимости каждый раз снова сканировать файл в поисках строки с нужным номером.
Встроенная переменная A_LoopReadLine существует внутри любого цикла чтения файла. Она содержит текст текущей строки, за исключением символов возврата каретки и перевода строки, отмечающих концы строк. Если цикл чтения файла находится внутри другого такого же цикла, текущая строка внутреннего цикла будет иметь преимущество.
Могут считываться строки длиной до 65534 символов. Если длина строки больше этой, её остаток будет считан в следующей итерации цикла.
Внутри цикла чтения файла часто используются команда StringSplit или цикл разбора, чтобы разбирать содержимое каждой строки, извлекаемой из InputFile. Например, если каждая строка в InputFile состоит из полей, разделённых табуляцией, эти поля могут извлекаться по отдельности, как в этом примере:
Loop, read, C:\Database Export.txt
{
Loop, parse, A_LoopReadLine, %A_Tab%
{
MsgBox, Поле номер %A_Index%: %A_LoopField%.
}
}
Для загрузки целого файла в переменную используйте команду FileRead, так как она работает быстрее, чем цикл (особенно для больших файлов).
Чтобы одновременно открыть несколько файлов, следуйте примеру, приведённому в описании команды DllCall.
Смотрите в описании команды Loop информацию о блоках кода, командах Break, Continue и переменной A_Index (которая существует во всех типах циклов).
Примеры
; Пример №1: только те строки из первого файла, которые содержат слово FAMILY, будут записаны во второй файл.
; Раскомментируйте первую строку, если нужно переписать существующий файл, а не добавить текст в него.
;FileDelete, C:\Docs\Family Addresses.txt
Loop, read, C:\Docs\Address List.txt, C:\Docs\Family Addresses.txt
{
IfInString, A_LoopReadLine, family, FileAppend, %A_LoopReadLine%`n
}
; Пример №2: возвращает последнюю строку текстового файла.
Loop, read, C:\Log File.txt
last_line := A_LoopReadLine ; По завершении цикла здесь будет содержаться последняя строка.
; Пример №3: скрипт пытается извлечь все адреса FTP и HTTP из текстового или HTML файла.
FileSelectFile, SourceFile, 3,, Выберите текстовый или HTML файл для анализа.
if SourceFile =
return ; В таком случае выйти.
SplitPath, SourceFile,, SourceFilePath,, SourceFileNoExt
DestFile = %SourceFilePath%\%SourceFileNoExt% Extracted Links.txt
IfExist, %DestFile%
{
MsgBox, 4,, Переписать существующий файл со ссылками? Нажмите "Нет", чтобы добавить.`n`nФайл: %DestFile%
IfMsgBox, Yes
FileDelete, %DestFile%
}
LinkCount = 0
Loop, read, %SourceFile%, %DestFile%
{
URLSearchString = %A_LoopReadLine%
Gosub, URLSearch
}
MsgBox %LinkCount% ссылок было найдено и записано в "%DestFile%".
return
URLSearch:
; Это делается именно так потому, что некоторые URL содержат внутри себя другие URL:
StringGetPos, URLStart1, URLSearchString, http://
StringGetPos, URLStart2, URLSearchString, ftp://
StringGetPos, URLStart3, URLSearchString, www.
; Найти самую левую стартовую позицию:
URLStart = %URLStart1% ; Задать старт по умолчанию.
Loop
{
; Это улучшает производительность (по крайней мере в скрипте со многими переменными),
; если "URLStart%A_Index%" вычисляется только один раз:
ArrayElement := URLStart%A_Index%
if ArrayElement = ; Достигнут конец массива.
break
if ArrayElement = -1 ; Этот элемент дисквалифицируется.
continue
if URLStart = -1
URLStart = %ArrayElement%
else ; URLStart содержит допустимую позицию, поэтому сравнить её с ArrayElement.
{
if ArrayElement <> -1
if ArrayElement < %URLStart%
URLStart = %ArrayElement%
}
}
if URLStart = -1 ; URLSearchString не содержит URL.
return
; Иначе извлечь этот URL:
StringTrimLeft, URL, URLSearchString, %URLStart% ; Опустить начальную/ненужную часть.
Loop, parse, URL, %A_Tab%%A_Space%<> ; Найти первый пробел, табуляцию или угловую скобку (если есть).
{
URL = %A_LoopField%
break ; т.е. совершается только одна итерация цикла, чтобы извлечь первое "поле".
}
; Если цикл выше совершил ноль итераций, поскольку не было найдено ни одного конечного символа,
; оставить содержимое переменной URL нетронутым.
; Если URL оканчивается двойной кавычкой, удалить её. Сейчас для этого используется StringReplace,
; но имейте в виду, что двойные кавычки, видимо, разрешены внутри URL, так что это может их повредить:
StringReplace, URLCleansed, URL, ",, All
FileAppend, %URLCleansed%`n
LinkCount += 1
; Нет ли в этой строке других URL:
StringLen, CharactersToOmit, URL
CharactersToOmit += %URLStart%
StringTrimLeft, URLSearchString, URLSearchString, %CharactersToOmit%
Gosub, URLSearch ; Рекурсивный вызов подпрограммой самой себя.
return