TiXL 本地文件 IO 操作符实战:FilesInFolder / ReadFile / WriteToFile 全解析
【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3
TiXL 的Lib.io.file操作符库把最常见的本地文件操作封装成了三个实时节点:扫描文件夹生成文件列表的FilesInFolder、把本地磁盘文件读取为字符串的ReadFile、以及把传入字符串写入本地文件的WriteToFile。这三者组合起来,可以在实时图形系统中完成素材自动发现、动态文本加载、参数状态导出等典型工作流。本文将基于 Lib.io.file 模块文档 及仓库源码,逐一讲解每个操作符的输入输出参数、底层实现原理和实战组合方式。
一、Lib.io.file 模块概览
Lib.io.file是 TiXL 操作符库中负责本地文件系统访问的模块,位于 Operators/Lib/Symbols/io/file/ 目录,包含三个核心操作符:
| 操作符 | 核心功能 | 数据流向 |
|---|---|---|
| FilesInFolder | 扫描文件夹中所有存在的文件并生成列表 | 文件系统 → List<string> |
| ReadFile | 读取本地磁盘文件,把内容输出为字符串 | 文件 → string |
| WriteToFile | 把传入的字符串写入本地磁盘的指定文件 | string → 文件 |
三者恰好覆盖了“列目录 → 读内容 → 写内容”的完整闭环:FilesInFolder负责发现素材,ReadFile负责把素材(如文本、配置)读入图内,WriteToFile负责把图内生成的数据持久化回磁盘。它们都与字符串操作、网络请求类操作符互为补充(详见后文“相关操作符”一节)。
每个操作符在仓库中同时包含三份文件:*.cs(C# 源码实现)、*.t3(符号定义)、*.t3ui(UI 布局),说明它们既是可运行的图节点,也是可以通过 .t3 文件复用的公开符号。
二、FilesInFolder:扫描文件夹并生成文件列表
FilesInFolder会扫描指定文件夹下所有文件,输出一个可直接接入PickFromStringList(从字符串列表中挑选)的文件路径列表,同时把文件数量作为整数输出。它常用于素材批量管理场景,例如把某个图片文件夹下的所有.jpg文件收集成列表,再配合选择器逐一播放。
详见官方文档:FilesInFolder.md
2.1 输入参数
| 名称(类型) | 说明 |
|---|---|
| Folder(String) | 定义被扫描的文件夹 / 路径 |
| Filter(String) | 指定文件夹内的所有文件名都会按此字符串进行匹配,只有匹配上的才会被选中。示例:.jpg、.obj、.png、.mp4、.txt、images-、slideshow_、animated_cat-等 |
| TriggerUpdate(Boolean) | 触发对选定文件夹及筛选条件的一次扫描 |
2.2 输出
| 名称 | 类型 |
|---|---|
| Files | System.Collections.Generic.List\1[System.String](即List `) |
| NumberOfFiles | System.Int32 |
2.3 源码实现细节
从 FilesInFolder.cs 的实现可以确认以下行为:
- 扫描方式:使用
Directory.GetFiles(_resolvedFolder)一次性获取目录下所有文件(非递归),再通过ToList()转为List<string>;若文件夹不存在则输出空列表而非报错。 - Filter 的匹配逻辑:当 Filter 为空时直接输出全部文件;否则使用
filepath.Contains(filter)做子串包含匹配(String.Contains),并非严格的正则或通配符匹配。所以写.png、images-、slideshow_这类片段都能命中对应文件。源码中 Filter 的默认值为"*.png"——注意此默认值虽然带*号,但实际生效的是“包含匹配”语义,与文档示例中的用法一致。 - Folder 默认值:输入槽默认初始化为
".",表示相对路径;实际使用前会经过TryGetFilePath解析为绝对路径_resolvedFolder。 - 触发时机:更新逻辑被
Files与NumberOfFiles两个输出共同绑定。当以下任一条件满足时才重新扫描:TriggerUpdate被触发(MathUtils.WasTriggered检测上升沿)、Folder变脏、或Filter变脏。扫描完成后会把TriggerUpdate重置为false,避免重复触发。 - 实时性设计:每次扫描结果同时更新
Files与NumberOfFiles,因此 UI 上文件列表与计数始终一致;由于依赖脏标记(DirtyFlag)机制,只有输入变化或手动触发时才会重扫,避免每帧都访问磁盘。
2.4 典型组合
文档明确推荐参考两个示例:FilesInFolderExample与FadingSlideShow。其中 FadingSlideShow.cs 位于render/basic目录,是“目录扫描 + 幻灯片轮播”的代表性用法:FilesInFolder输出图片文件列表,配合选择/索引节点选出当前帧要显示的图片,再交给图像渲染节点实现多图淡入淡出的轮播效果。这种“扫描文件夹即得素材清单”的模式,是 TiXL 中做动态内容展示的常用套路。
三、ReadFile:把本地文件读为字符串
ReadFile读取本地磁盘上的一个文件,并把其全部内容输出为一个字符串。它的反操作是WriteToFile。最常见的用法是把文本配置、代码片段或数据文件读入图内,再交给PickStringPart(字符串提取)等节点做进一步加工。
详见官方文档:ReadFile.md
3.1 输入参数
| 名称(类型) | 说明 |
|---|---|
| FilePath(String) | 选择要被读取的文件 |
| TriggerUpdate(Boolean) | 触发对选定文件的一次重新读取 |
3.2 输出
| 名称 | 类型 |
|---|---|
| Result | System.String |
3.3 源码实现细节
ReadFile.cs 的实现体现了 TiXL 资源管理框架的典型用法:
- 资源缓存机制:构造函数中通过
new Resource<string>(FilePath, TryLoad)建立“文件路径 → 内容”的资源绑定,并把Result槽注册为该资源的依赖槽。资源框架负责跟踪文件变化,避免无谓的重复磁盘 IO。 - 文件读取:
TryLoad回调中调用FileResource.TryOpenFileStream打开文件流(FileAccess.Read),再以StreamReader.ReadToEnd()读出完整文本作为新值。 - 手动刷新:
TriggerUpdate槽的更新动作会调用_fileContents.MarkFileAsChanged(),强制资源框架认为文件已变化并重新加载——这是文档所说“触发对选定文件的一次重新扫描”的底层实现,适合文件在外部被改动后手动拉取最新内容。 - 错误处理:文件打开或读取失败时,会记录失败原因并
LogErrorState输出错误状态;成功读取后调用ClearErrorState()清除错误,方便在 UI 上呈现失败反馈。 - 辅助接口:该类实现了
IDescriptiveFilename接口(提供FileFilter与SourcePathSlot),说明它在编辑器中被视为“带文件名描述的节点”,可以参与资源路径相关的 UI 交互与资产识别。其默认文件过滤器为["*"],即默认接受任意文件。
四、WriteToFile:把字符串写入本地文件
WriteToFile把进入节点的字符串写入本地磁盘的指定文件,常用来把图内生成的文本数据(如导出配置、统计结果、动画参数快照)持久化到磁盘。
详见官方文档:WriteToFile.md
4.1 输入参数
| 名称(类型) | 说明 |
|---|---|
| Content(String) | 输入 / 定义要写入文件的内容字符串 |
| Filepath(String) | 要写入的目标文件路径。文档给出的示例:Resources\user\YourUserName\FileName.txt——将打开FileName.txt并把传入字符串写入其中 |
4.2 输出
| 名称 | 类型 |
|---|---|
| Result | System.String |
| OutFilepath | System.String |
4.3 源码实现细节与注意事项
WriteToFile.cs 的实现要点如下:
- 按需写入:
Update中会比较Content与Filepath是否相对上次发生变化,只有两者之一变化时才真正执行写入(TryWrite),否则直接透传输出,避免每帧重复写盘。注意OutFilepath输出槽标记了DirtyFlagTrigger = DirtyFlagTrigger.Animated,便于下游节点感知路径更新。 - 路径解析:写入前通过
AssetRegistry.TryResolveAddressForWriting把 TiXL 内的资源地址(如Resources\user\...这样的项目相对路径)解析为操作系统绝对路径;解析失败会记录错误状态并中止写入。这就是文档示例中相对路径写法能够生效的底层机制。 - 目录与文件创建:源码会先执行
Directory.CreateDirectory确保目标目录存在,再调用File.WriteAllText(absolutePath, content ?? string.Empty)写入文本(内容为空时写入空字符串)。此处需注意与文档表述的差异:文档注明“此操作符无法创建文件,文件必须已存在才能写入”,而当前仓库实现已具备自动创建目录与文件的能力——若你在较旧版本或遇到权限限制时,应优先确保目标文件存在,并检查用户权限。 - 权限提示:文档特别提醒,根据用户与操作系统的不同,Tooll(TiXL)可能需要对写入位置具有管理员权限,尤其是在写入系统保护目录时。
- 错误反馈:写入抛出的异常会被捕获并记录为错误状态(
LogErrorState),同时保留上次成功值,不会让节点崩溃。
五、三者组合:一套完整的本地文件工作流
把三个操作符串起来即可形成完整的文件闭环,例如:
FilesInFolder扫描某个素材文件夹(Filter 设为.txt),得到全部文本文件路径列表;- 用
PickFromStringList(或索引类节点)从列表中选出当前要处理的文件; - 将选中的路径送入
ReadFile的FilePath,得到文件内容字符串; - 对内容做变换(如用 PickStringPart 提取子串、拼装新文本)后,送入
WriteToFile写回磁盘,实现“读→改→写”的批处理; - 通过
WriteToFile的TriggerUpdate/ 变化检测,或FilesInFolder的手动触发,控制读写发生的时机。
这种工作流很适合做实时演出中的动态数据交换:外部工具(如网页、脚本、其他软件)向文件夹写入文本,TiXL 用FilesInFolder+ReadFile轮询并驱动画面;反过来,TiXL 用WriteToFile把状态导出给外部工具消费。
六、相关操作符与延伸阅读
Lib.io.file文档还提到了几个功能互补的操作符:
- RequestUrl:为文件 IO 增加“在线能力”,把本地文件读取扩展到远程 URL 请求;
- PickStringPart:从字符串中提取子串,常与
ReadFile配合对读取内容做结构化裁剪,其文档位于 PickStringPart.md; - GetAttributeFromJsonString:从 JSON 字符串中按属性名取值,适合配合
ReadFile读取 JSON 配置后直接提取字段,文档位于 GetAttributeFromJsonString.md; - WriteToFile的反操作是
ReadFile;ReadFile的在线版是RequestUrl。
在编辑器中使用时,这些操作符会出现在操作符选择器的Lib.io.file分类下;它们的符号定义与 UI 布局分别保存在*.t3与*.t3ui文件中(见 Operators/Lib/Symbols/io/file/),源码实现则位于同目录下的*.cs文件,便于进阶用户直接阅读或二次开发。
七、总结
Lib.io.file的三个操作符构成了 TiXL 本地文件访问的最小完整集:FilesInFolder解决“发现文件”,ReadFile解决“读取内容”,WriteToFile解决“持久化输出”。通过它们的参数设计(TriggerUpdate手动刷新、Filter字符串筛选、资源缓存与脏标记触发机制),用户可以精确控制文件 IO 发生的时机与范围,在实时渲染循环中安全、高效地与本地文件系统交互。结合FadingSlideShow、PickStringPart、GetAttributeFromJsonString等配套节点,这套工具足以支撑素材管理、动态配置、数据导出等绝大多数实战场景。
【免费下载链接】t3TiXL is an open source software to create realtime motion graphics.项目地址: https://gitcode.com/GitHub_Trending/t3/t3
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考