获取 FTP 服务器文件和目录列表

FTP 客户端需要获取服务器当前目录中的文件和目录列表,其中应包含尽可能多的信息(日期、大小、用户、组、访问权限等)。这些文件和目录显示在面板中,供您操作。文件和目录列表来自 FTP 服务器返回的纯文本列表。此列表设计为供人阅读,而非自动解析,因此几乎每种 FTP 服务器都有自己的列表格式(取决于服务器操作系统、语言版本等),客户端必须处理多种格式。

每种列表格式都定义一个服务器类型,其中包含自动检测条件、可用数据列及其是否在面板中显示,以及纯文本列表解析器。全部已定义服务器类型显示在配置/服务器中。您可在编辑服务器类型对话框中添加新类型或编辑现有类型。

您可选择是否自动检测服务器类型。如不自动检测,则选择要使用的类型。参见服务器类型选项,位于高级选项对话框中。

使用指定服务器类型获取文件和目录列表

使用指定服务器类型解析纯文本列表。成功时,得到文件和目录列表;失败时,插件显示警告,面板中仅显示纯文本列表(无法对其执行任何操作)。

目录 "."(如在列表中)和目录 ".."(如在列表中,且列表属于根目录)会从文件和目录列表中移除。目录 ".." 如在列表中,则始终显示,忽略隐藏属性。

使用自动检测的服务器类型获取文件和目录列表

逐一尝试全部已定义服务器类型,并计算各类型的自动检测条件。条件为假时,跳过该类型并尝试下一个;为真时,使用该类型解析纯文本列表。解析成功则得到文件和目录列表,失败则跳过并尝试下一个。

如果没有任何服务器类型成功解析,则逐一尝试之前因自动检测条件而跳过的类型。使用各类型解析纯文本列表,成功则得到文件和目录列表,失败则跳过并尝试下一个。

如果所有已定义服务器类型均解析失败,插件会显示警告,面板中仅显示纯文本列表(无法对其执行任何操作)。

仅在服务器返回第一个列表时自动检测类型。后续列表均使用相同类型,这也使插件能够对空列表等情况显示相同的列。如果使用该类型无法解析列表,插件会尝试自动检测其他类型。

目录 "."(如在列表中)和目录 ".."(如在列表中,且列表属于根目录)会从文件和目录列表中移除。目录 ".." 如在列表中,则始终显示,忽略隐藏属性。

解析器语法

行注释以 "#" 字符开始,在行结束符处结束。

每条规则以 "*" 开始,以 ";" 结束。规则数量不限,由以 "," 分隔的函数组成。

函数由名称、"("、参数列表和 ")" 组成。完整的函数列表见本页下方。

参数列表中的参数以 "," 分隔。参数为表达式。

表达式可以是列标识符、状态变量、常量或一个二元运算。二元运算采用标准形式(first_operand operation_symbol second_operand)。操作数可以是列标识符、状态变量或常量。

列标识符由 '<' 字符、标识符名称和 '>' 字符组成。

状态变量和运算符号的完整列表见本页下方。

常量可以是字符串、数字或布尔值。

字符串用双引号('"' 字符)括起,必须定义在单行内。转义序列以 '\' 字符开始。支持的转义序列有:"\\" 表示 '\',"\"" 表示 '"',"\t" 表示制表符,"\r" 和 "\n" 表示行结束字符(CR 和 LF)。其他转义序列会报告为语法错误。

数字由十进制数字组成。负数以 "-" 开头,正数以 "+" 开头(可省略)。

布尔值为 "true" 或 "false",不带双引号。

列

每列都有标识符名称、值类型、空值、用于面板显示的名称和说明,以及值的对齐方式。标识符名称用于列标识符,后者用于为列赋值。每列对每个项目(文件或目录)只能包含一个值。如果未赋值,则使用为该列定义的空值。列可在面板中显示或隐藏,但“名称”和“扩展名”类型始终显示。列定义于新建/编辑列对话框。

支持以下列类型:

类型说明
名称字符串;文件或目录名称;必须恰好有一列属于此类型,且不可隐藏;为此列定义空值没有意义;解析器必须为每个文件和目录的此列赋值;未赋值时,当前规则不会添加任何文件或目录(用于跳过空行和纯文本列表中其他不重要部分);赋为空字符串("")视为解析错误
扩展名字符串;文件扩展名;值根据“名称”类型列的值自动生成;不可隐藏;为此列定义空值没有意义
文件大小(字节)64 位无符号整数;文件大小,以字节为单位;对所有目录,其值为零,在面板中显示为 "DIR";默认空值为零
上次写入日期日期;上次写入(修改)日期;日期必须有效,否则替换为 1602 年 1 月 1 日;默认空值为 1602 年 1 月 1 日
上次写入时间时间;上次写入(修改)时间;默认空值为 0:00:00
文件类型字符串;文件类型说明(Windows 为各扩展名定义);值根据“名称”类型列的值自动生成;为此列定义空值没有意义
任意文本字符串;通用用途;默认空值为空字符串("")
任意日期日期;通用用途;日期必须有效,否则替换为 1602 年 1 月 1 日;默认空值为空字符串(""),即未赋值时,面板不显示任何内容
任意时间时间;通用用途;默认空值为空字符串(""),即未赋值时,面板不显示任何内容
任意数字64 位有符号整数;通用用途;默认空值为空字符串(""),即未赋值时,面板不显示任何内容

另有三个虚拟列,标识符为 <is_dir>、<is_hidden> 和 <is_link>。为这些列赋布尔值,分别表示“此项目是否为目录?”(false 表示文件)、“此项目是否隐藏?”(false 表示没有隐藏属性)和“此项目是否为链接?”(false 表示不是链接)。不必为这些列赋值;其空值分别表示“是文件”“不隐藏”和“不是链接”。

自动检测条件语法

自动检测条件是逻辑表达式。运算符按优先级从高到低为 NOT、AND 和 OR。NOT(逻辑非)是一元运算,AND(逻辑与)和 OR(逻辑或)是二元运算。表达式可包含括号包围的子表达式。以下函数用作操作数:

函数说明
syst_contains(string)仅当 FTP 命令 SYST(获取服务器操作系统类型)的响应包含指定字符串时返回 true;搜索不区分大小写
welcome_contains(string)仅当服务器的首条消息包含指定字符串时返回 true;搜索不区分大小写
reg_exp_in_syst(regular_expression_string)仅当 FTP 命令 SYST(获取服务器操作系统类型)的响应包含匹配指定正则表达式的字符串时返回 true;搜索不区分大小写
reg_exp_in_welcome(regular_expression_string)仅当服务器的首条消息包含匹配指定正则表达式的字符串时返回 true;搜索不区分大小写

解析

使用已定义规则完整遍历纯文本列表后,解析即成功。

列表中的当前位置称为指针。解析过程中,指针从列表开头移至末尾。

仅当规则内全部函数均计算成功、未将空字符串赋给“名称”类型列(即只能赋非空字符串或不赋值),且指针移到列表某行末尾时,规则才可使用。每次使用规则后,指针始终移到下一行开头。

函数计算时可移动指针,以及为列赋值或更改列值。

解析器可包含任意数量的规则。始终按定义顺序尝试规则,即总是使用第一个可用规则。

用户取消列表传输或发生网络故障时,列表可能不完整。不完整列表会被截取为仅保留完整文本行。

不完整列表的解析在应用规则这一层处理。简单情况下,通过规则将指针移到不完整列表末尾,即表示解析成功结束。否则,当前规则的某个函数在计算时应将指针移到下一行,但由于列表不完整而无法进行,因此解析仍成功结束;这相当于当前规则遍历的行原本就不在不完整列表中。

支持的文件大小

插件支持两种文件大小:以字节计和以块计。以字节计的文件大小应赋给“文件大小(字节)”类型列;以块计的文件大小应赋给“任意数字”类型列,并使用标准名称 "Blocks" 或 "BlkSize"。这样,选择一组文件时,就会在信息行显示总字节数或总块数。

解析函数

除非明确说明,否则函数始终成功、不移动指针,且不为任何列赋值。如果函数会移动指针,且无明确说明,则假定指针不能越过行尾到下一行。

在表达式中使用列标识符之前,必须先为该列赋值。否则表达式没有意义(可替换为使用该列默认空值计算所得的布尔常量)。

注意:下表中的空白字符指空格或制表符。

支持以下解析函数:

函数说明
if(expression)表达式(expression 参数)的结果类型必须为布尔值;结果为 true 时,函数成功
assign(<column>, expression)表达式(expression 参数)的结果类型必须与列(<column> 参数)的值类型相同;将表达式结果赋给该列
skip_white_spaces()跳过指针位置的所有空白字符;如有,则将指针移到它们之后
skip_to_number()将指针移到最近的十进制数字
white_spaces()跳过指针位置的所有空白字符;仅当指针发生移动时,函数才成功
white_spaces(number)跳过指针位置处由指定数量(number 参数)空白字符组成的字符串,将指针移到其后;仅当此字符串存在时,函数才成功
white_spaces_and_line_ends()跳过指针位置的全部空白字符和行结束符;仅当指针发生移动,且未到达列表末尾(即在空白和行结束符之后找到了其他字符)时,函数才成功
rest_of_line()将指针移到行尾;仅当指针发生移动时,函数才成功
rest_of_line(<column>)列(<column> 参数)的值类型必须为字符串;将从指针位置到行结束符之前的字符串赋给该列;指针移到行尾;仅当指针发生移动时,函数才成功
word()跳过除空白和行结束符之外的所有字符;仅当指针发生移动时,函数才成功
word(<column>)列(<column> 参数)的值类型必须为字符串;将从指针位置到第一个空白或行结束符之前的字符串赋给该列;指针移到其后;仅当指针发生移动时,函数才成功
number(<column>)列(<column> 参数)的值类型必须为整数;将从指针位置开始的十进制数字赋给该列;数字后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到数字之后;仅当数字存在且结尾正确时,函数才成功;若列类型为“文件大小(字节)”,还要求数字不为负数
positive_number(<column>)列(<column> 参数)的值类型必须为整数;将从指针位置开始的正十进制数字赋给该列;如果为负数,则改赋默认空值(“文件大小(字节)”类型为零,“任意数字”类型为空字符串);数字后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到数字之后;仅当数字存在且结尾正确时,函数才成功
number_with_separators(<column>, string) 列(<column> 参数)的值类型必须为整数;将从指针位置开始、带数字分组符的十进制数字赋给该列。分组符便于阅读大数,由 string 参数指定,除十进制数字及 "+"、"-" 外均可使用;数字后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到数字之后;仅当数字存在且结尾正确时,函数才成功;若列类型为“文件大小(字节)”,还要求数字不为负数
month_3(<column>)列(<column> 参数)的值类型必须为日期;将指针位置处以三个字母表示的月份赋给该列;支持多种语言的月份名称,目前为英语、德语、挪威语和瑞典语;月份名称后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到月份名称之后;仅当月份名称已知,且列表中的所有月份名称均属于同一语言时,函数才成功
month_3(<column>, string)列(<column> 参数)的值类型必须为日期;将指针位置处以三个字母表示的月份赋给该列;月份名称由字符串(string 参数)指定,其中包含以空格分隔的十二个三字母月份名称,例如英语为 "jan feb mar apr may jun jul aug sep oct nov dec";名称后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到月份名称之后;仅当月份名称在字符串中时,函数才成功
month_txt(<column>)列(<column> 参数)的值类型必须为日期;将指针位置处以名称表示的月份赋给该列;支持多种语言的月份名称,目前支持德语;名称后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到月份名称之后;仅当月份名称已知,且列表中的所有月份名称均属于同一语言时,函数才成功
month_txt(<column>, string)列(<column> 参数)的值类型必须为日期;将指针位置处以名称表示的月份赋给该列;名称由字符串(string 参数)指定,其中包含以空格分隔的十二个月份名称,例如德语为 "Jan. Feb. März Apr. Mai Juni Juli Aug. Sept. Okt. Nov. Dez.";名称后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到月份名称之后;仅当月份名称在字符串中时,函数才成功
month(<column>)列(<column> 参数)的值类型必须为日期;将指针位置处以十进制数字表示的月份赋给该列;数字后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到数字之后;仅当数字在 1 至 12 范围内时,函数才成功
day(<column>)列(<column> 参数)的值类型必须为日期;将指针位置处以十进制数字表示的日赋给该列;数字后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到数字之后;仅当数字在 1 至 31 范围内时,函数才成功
year(<column>)列(<column> 参数)的值类型必须为日期;将指针位置处以十进制数字表示的年份赋给该列;数字后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到数字之后;仅当数字在 0 至 999 范围内(0 至 79 加 2000,80 至 999 加 1900,例如 107 表示 2007 年),或在 1602 至 9999 范围内时,函数才成功
time(<column>)列(<column> 参数)的值类型必须为时间;将指针位置处以十进制数字表示的小时、分钟,以及可选的秒和毫秒赋给该列;支持格式为 00:00、00:00:00 或 00:00:00.000;若时间后带 "a"、"am"、"p" 或 "pm",则视为 "a.m."(上午)或 "p.m."(下午),并相应调整时间值;时间后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母或数字;指针移到时间之后;仅当时间有效时,函数才成功,范围分别为 0-23、0-59、0-59 和 0-999
year_or_time(<column_date>, <column_time>) 列(<column_date> 和 <column_time> 参数)的值类型必须分别为日期和时间;将指针位置处的年份及可选时间(仅小时和分钟)赋给相应列,年份为十进制数字,时间为以 ":" 分隔的两个十进制数字;支持标准 Unix 格式:若指针处是年份,则时间未知;若是时间,则根据当前日期推算年份,使完整日期不早于六个月之前;数字后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到年份或时间之后;仅当年份或时间有效时,函数才成功,范围为 1602-9999 和 0-23:0-59
all(number)跳过指定数量(number 参数)的字符,并将指针移到其后;仅当全部指定字符均被跳过时,函数才成功
all(<column>, number)列(<column> 参数)的值类型必须为字符串;将从指针位置开始、包含指定数量字符(number 参数)的字符串赋给该列;指针移到其后;仅当此字符串存在时,函数才成功
all_to(string)查找指定字符串(string 参数)首次出现的位置,不区分大小写,并将指针移到其后;仅当找到指定字符串时,函数才成功
all_to(<column>, string)列(<column> 参数)的值类型必须为字符串;将从指针位置到指定字符串(string 参数)首次出现位置之后的字符串赋给该列,搜索不区分大小写;指针移到找到的字符串之后;仅当找到指定字符串时,函数才成功
all_up_to(<column>, string)列(<column> 参数)的值类型必须为字符串;将从指针位置到指定字符串(string 参数)首次出现位置之前的字符串赋给该列,搜索不区分大小写;指针移到找到的字符串之后;仅当找到指定字符串时,函数才成功
unix_link(<is_dir>, <column_name>, <column_link>)列 <column_name> 和 <column_link> 的类型必须分别为“名称”和“任意文本”;处理从指针位置到行尾之前的字符串,并将指针移到其后;预期标准 Unix 链接格式为 "link_name -> target_name",或目标不可访问时的 "link_name";从字符串获取链接名称及可选目标,并判断它指向文件还是目录。启发式规则为:链接名称或目标带扩展名时,可能指向文件,否则指向目录;若不适用,可在 unix_link 后添加 "assign(<is_dir>,false)" 等函数。将链接名称赋给 <column_name> 列,已知目标赋给 <column_link> 列;如果指向目录,则将 true 赋给 <is_dir> 虚拟列;仅当字符串符合预期格式且不以空白开头时,函数才成功
unix_device(<column>)列(<column> 参数)的值类型必须为字符串;将从指针位置开始、包含由逗号和若干空格分隔的两个十进制数字(例如 "27, 26")的字符串赋给该列;字符串后必须为常见分隔符(逗号、点、分号、冒号等)、空白或行结束符,不能为字母;指针移到字符串之后;仅当找到该字符串时,函数才成功
add_string_to_column(<column>, expression) 列(<column> 参数)的值类型及表达式(expression 参数)的结果类型必须均为字符串;将表达式结果追加到列值
cut_white_spaces_end(<column>)列(<column> 参数)的值类型必须为字符串;去除列内字符串末尾的空白字符,并将新字符串赋给该列
cut_white_spaces_start(<column>)列(<column> 参数)的值类型必须为字符串;去除列内字符串开头的空白字符,并将新字符串赋给该列
cut_white_spaces(<column>)列(<column> 参数)的值类型必须为字符串;去除列内字符串首尾的空白字符,并将新字符串赋给该列
back(number)将指针向后移动指定数量(number 参数)的字符;仅当可以执行此移动时,函数才成功,不可将指针移到上一行
cut_end_of_string(<column>, number)列(<column> 参数)的值类型必须为字符串;从列内字符串末尾去除指定数量(number 参数)的字符,并将新字符串赋给该列;仅当原始列值长度至少为 number 时,函数才成功

解析中使用的状态变量

支持以下状态变量:

变量说明
first_nonempty_line布尔值;仅当指针位于第一个非空行(不只是包含空白字符的行)时为 true
last_nonempty_line布尔值;仅当指针位于最后一个非空行(不只是包含空白字符的行)时为 true;不考虑列表是否完整
next_char字符串;包含指针位置的一个字符;指针位于列表末尾时为空字符串
next_word字符串;从指针位置到第一个空白或行结束符之前的字符串
rest_of_line字符串;从指针位置到行结束符之前的字符串

解析中使用的运算符

在表达式中使用列标识符之前,必须先为该列赋值。否则表达式没有意义(可替换为使用该列默认空值计算所得的布尔常量)。

支持以下运算符:

运算符说明
==相等;字符串比较区分大小写
!=不相等;字符串比较区分大小写
eq字符串相等;仅适用于字符串;比较不区分大小写
not_eq字符串不相等;仅适用于字符串;比较不区分大小写
in子串搜索;仅当左操作数的子串存在于右操作数的字符串中时为 true;比较不区分大小写
not_in仅当左操作数的子串不存在于右操作数的字符串中时为 true;比较不区分大小写
end_with仅当左操作数的字符串以右操作数的子串结尾时为 true;比较不区分大小写
not_end_with仅当左操作数的字符串不以右操作数的子串结尾时为 true;比较不区分大小写

另请参阅

配置/服务器
编辑服务器类型对话框
新建/编辑列对话框
解析器测试对话框

From the Sally manual (GPL-2.0-or-later), © 1997-2023 Open Salamander Authors; © 2025-2026 Elias Bachaalany. Source: manual source (zip) · original page in the Sally repository