文档知识库教程OpenHarmony【免费下载链接】CangjieCorpus本仓库为仓颉编程语言语料库聚焦 仓颉编程语言 核心知识体系整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源经结构化处理与专业标注构建为支持 RAG检索增强生成技术 的高质量知识基座适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用推动鸿蒙开发生态智能化升级项目地址https://gitcode.com/Cangjie/CangjieCorpus点击查看免费下载本篇技术指南围绕仓颉编程语言Cangjie的I/O 节点流展开系统讲解标准流Console封装的标准输入/输出/错误流与文件流std.fs包的File类型的概念、API 用法与底层实现原理。读者学完后将掌握如何在命令行程序中读取键盘输入、向屏幕输出内容以及如何通过常规文件操作、流式读写和 try-with-resource 语法高效地处理文件数据。文中所有结论均有本仓库内的官方文档与 API 源码佐证可直接对照验证。什么是节点流仓颉编程语言将程序与外部载体交互的操作抽象为I/OInput 对应输入Output 对应输出所有 I/O 机制都基于数据流Stream进行流本质上是字节数据的有序序列就像承载数据的管道参见 I/O 流概述。按照职责差异流可分成两类节点流Node Stream直接提供数据源其构造方式通常依赖某种直接的外部资源如文件、网络等处理流Process Stream只能代理其他数据流进行处理构造方式通常依赖其他流如缓冲流、字符串流详见姊妹篇 I/O 处理流。仓颉编程语言中常见的节点流包括节点流数据源标准流StdIn、StdOut、StdErr键盘、终端屏幕文件流File文件系统中的文件网络流Socket网络连接本章重点介绍标准流和文件流两类最常用的节点流。标准流程序与外部交互的标准接口标准流包含三个部分标准输入流stdin程序从外部读取数据的通道默认来源于键盘输入例如命令行界面中输入的文本标准输出流stdout程序输出运行结果的通道默认输出到屏幕标准错误流stderr程序输出错误信息的通道默认也输出到屏幕。在 Unix/Linux 系统中标准输入、标准输出和标准错误分别对应文件描述符 0、1 和 2参见 std.console 包概览。在仓颉编程语言中可以通过Console类型分别访问它们。导入 console 包使用Console类型需要先导入console包import std.console.*Console对三个标准流都进行了易用性封装提供了更方便的基于String的扩展操作并且针对很多常见类型整数、浮点数、布尔值、Rune、String等都提供了丰富的write重载来优化性能。其中最重要的是Console提供了并发安全的保证可以在任意线程中安全地通过Console提供的接口来读写内容。说明在 API 文档中std.console包被标记为deprecated未来版本将废弃届时可使用env包中的相应函数替代详见 console 包类定义。本文示例基于当前仓库实际 API 编写。读取标准输入stdIn当需要从标准输入流中获取数据时可以通过Console.stdIn来读取例如通过readln函数获取命令行的输入import std.console.* main() { let txt Console.stdIn.readln() println(txt ?? ) }运行上面的代码在命令行上输入一些文字然后换行结束即可在屏幕上看到输入的内容。从源码看Console.stdIn的类型是ConsoleReader其声明见 console 包类定义该类实现了InputStream接口提供了多种读取方式read(): ?Rune从标准输入中读取下一个字符输入不符合 UTF-8 编码时抛出IllegalArgumentExceptionread(arr: ArrayByte): Int64将读取的字节放入数组并返回字节长度注意可能将 UTF-8 码点从中截断导致转字符串结果不正确或抛异常readln(): ?String读取一行字符串结果不包含末尾换行符读取失败返回NonereadToEnd(): ?String读取所有字符直到 EOFLinux 键入CtrlD、Windows 键入CtrlZ加回车readUntil(predicate: (Rune) - Bool): ?String与readUntil(ch: Rune): ?String按条件或按终止字符读取。ConsoleReader只有一个实例所有方法共享同一个缓存区。读操作是同步的内部设有缓存区保存控制台输入内容当到达控制台输入流结尾时读取函数返回None。readln的返回值是?String可空类型因此上面的示例使用?? 提供缺省值。写入标准输出与标准错误stdOut / stdErr输出流分为标准输出流和标准错误流默认情况下它们都会输出到屏幕。当需要写入数据时可以通过Console.stdOut/Console.stdErr写入例如使用write/writeln函数向命令行打印内容import std.console.* main() { for (i in 0..1000) { Console.stdOut.writeln(hello, world!) } Console.stdOut.flush() }使用stdOut与直接使用print函数相比有两个显著差别并发安全ConsoleWriter保证线程安全每次write调用写到控制台的结果是完整的不同 write 调用之间的结果不会混合见 console 包类定义缓存与性能stdOut使用了缓存技术在输入内容较多时拥有更好的性能表现。需要注意写完数据后需要对stdOut调用flush才能保证内容被真正写到标准流中。这是因为ConsoleWriter的输出带有缓冲策略数据先进入缓冲区只有缓冲区被填满或主动调用flush时才真实写入这与OutputStream接口中flush的设计一致参见 I/O 接口定义。ConsoleWriter实现了OutputStream接口并提供了丰富的重载write/writeln支持ArrayByte、Bool、Float16/Float32/Float64、Int8/Int16/Int32/Int64、UInt8/.../UInt64、Rune、String以及泛型版本writeT(v: T) where T : ToString这意味着任何实现了ToString接口的自定义类型都可以直接写入标准流。参考 Console 官方示例一个完整的交互程序可以这样写import std.console.* main() { Console.stdOut.write(请输入信息1) var c Console.stdIn.readln() var r c.getOrThrow() Console.stdOut.writeln(输入的信息1为 r) Console.stdOut.write(请输入信息2) c Console.stdIn.readln() r c.getOrThrow() Console.stdOut.writeln(输入的信息2为 r) }运行结果用户依次输入两行内容请输入信息1你好请问今天星期几 输入的信息1为你好请问今天星期几 请输入信息2你好请问今天几号 输入的信息2为你好请问今天几号文件流基于 fs 包的统一文件系统接口仓颉编程语言提供了fs包来支持通用文件系统任务。不同操作系统对文件系统提供的接口有所不同仓颉抽象出共通功能通过统一接口屏蔽操作系统差异来简化使用当前支持 Linux、macOS、Windows 和 HarmonyOS 平台见 std.fs 包概览。常规操作任务包括创建文件/目录、读写文件、重命名或移动文件/目录、删除文件/目录、复制文件/目录、获取文件/目录元数据、检查文件/目录是否存在。使用文件系统相关功能需要导入fs包import std.fs.*File类型在仓颉编程语言中同时提供了常规文件操作和文件流两类功能。对于Path和Directory的使用可以查阅 fs 包 API。常规文件操作静态函数一族对于常规文件操作可以使用一系列静态函数完成快捷操作。检查文件是否存在使用exists函数返回true表示文件存在反之不存在。import std.fs.* main() { let exist exists(./tempFile.txt) println(exist: ${exist}) }移动、拷贝和删除文件File同样提供了对应的静态函数copy、rename、remove源码中它们实际上是fs包顶层函数见 fs 包函数定义import std.fs.* main() { copy(./tempFile.txt, to: ./tempFile2.txt, overwrite: false) rename(./tempFile2.txt, to: ./tempFile3.txt, overwrite: false) remove(./tempFile3.txt) }结合源码这三个函数的关键语义是copy(sourcePath, to!, overwrite! false)复制文件或目录。目标位置存在且overwrite为true时要求源与目标类型一致如源为目录则目标也须为目录overwrite为false且目标已存在时抛出FSExceptionrename(sourcePath, to!, overwrite! false)重命名或移动。overwrite为true时会删除目标位置的原有文件或目录若目标是目录会递归删除其中所有内容需谨慎使用remove(path, recursive! false)删除文件或目录删除文件夹时可选择是否递归。此外还有removeIfExists存在则删除并返回true、canonicalize规范化路径等函数可查阅 fs 包函数定义。一次性读写整个文件如果需要直接将文件的所有数据读出来或一次性将数据写入文件可以使用File提供的静态函数readFrom、writeToimport std.fs.* main() { let bytes File.readFrom(./tempFile.txt) // 一次性读取了所有的数据 File.writeTo(./otherFile.txt, bytes) // 把数据一次性写入另一个文件中 }从源码fs 包类定义看File.readFrom(path)以字节数组形式返回文件全部内容文件不存在或不可读时抛出FSExceptionFile.writeTo(path, buffer)以覆盖方式写入文件存在时会先截断为零字节大小文件不存在则创建配套的File.appendTo(path, buffer)以追加方式写入文件不存在则创建适合日志累加等场景。在数据量较少的情况下这类函数既简单易用又能提供较好的性能表现无需手动处理数据流但若要处理大文件或需要精细控制则应使用下面的文件流操作。文件流操作File 即数据流除了常规文件操作File类型本身也被设计为一种数据流类型实现了IOStream接口。当创建了一个File实例就可以把它当成数据流来使用。File 类定义见 fs 包类定义public class File : Resource IOStream Seekable { ... }这一声明揭示了三个关键能力Resource实现close()与isClosed()可配合 try-with-resource 语法自动释放资源见 core 包 Resource 接口IOStream同时具备InputStream.read与OutputStream.write/flush能力见 I/O 接口定义Seekable提供length、position、remainLength属性与seek函数支持移动读写光标配合SeekPosition枚举Begin、Current、End实现定位读取见 I/O 枚举定义。两种构造方式File提供了两种构造方式静态函数create直接创建新文件实例。注意create创建的文件是只写的不能对实例进行读操作否则会抛出运行时异常且当文件已存在或上级目录不存在时抛出FSException构造函数传入打开模式通过File(path, mode)构造新实例。File 构造示例// 创建 internal import std.fs.* internal import std.io.* main() { let file File.create(./tempFile.txt) file.write(hello, world!.toArray()) // 打开 let file2 File(./tempFile.txt, Read) let bytes readToEnd(file2) // 读取所有数据 println(bytes) }这里使用了std.io包提供的readToEnd(from)函数读取入参中所有未被读取的数据以字节数组返回见 io 包函数定义。io包还提供了readString校验 UTF-8、readStringUnchecked不校验、copy(from, to!)等流工具函数。OpenMode 打开模式当需要更精细的打开模式时可以使用构造函数传入一个OpenMode值。OpenMode是一个enum类型提供了丰富的文件打开模式见 fs 包枚举定义public enum OpenMode : ToString EquatableOpenMode { | Read | Write | Append | ReadWrite }模式语义Read只读方式打开。文件不存在时抛出FSExceptionWrite只写方式打开。文件存在时截断为零字节大小文件不存在则创建Append追加写入方式打开。文件不存在则创建写入位置始终在文件末尾ReadWrite可读可写方式打开。文件不存在则创建但不会将文件截断为零字节File 打开模式使用示例// 使用指定选项打开模式 let file File(./tempFile.txt, Write)资源释放与 try-with-resource打开File实例会占用宝贵的系统资源文件句柄使用完后需要及时关闭File以释放资源。File实现了Resource接口在大多数时候都可以使用try-with-resource语法来简化使用try (file2 File(./tempFile.txt, Read)) { ... // 结束使用后自动释放文件 }该语法会在代码块结束时自动调用close()释放文件即使块中抛出异常也会保证资源被关闭避免资源泄露。API 文档特别提醒创建的File对象会默认打开对应文件使用结束后需要及时调用close关闭文件见 fs 包类定义。流式读写综合示例参考 fs 包 File 官方示例可以综合看到四种OpenMode与SeekPosition、setLength的配合用法import std.fs.* import std.io.* main() { let filePath: Path Path(./tempFile.txt) if (exists(filePath)) { remove(filePath) } /* 以只写模式创建新文件写入三遍 123456789\n 并关闭 */ var file: File File(filePath, Write) let bytes: ArrayByte 123456789\n.toArray() for (_ in 0..3) { file.write(bytes) } file.close() /* 以追加模式打开写入 abcdefghi\n 并关闭 */ file File(filePath, Append) file.write(abcdefghi\n.toArray()) file.close() /* 以只读模式打开用 seek 定位后读取数据 */ file File(filePath, Read) let bytesBuf: ArrayByte ArrayByte(10, repeat: 0) file.seek(SeekPosition.Begin(10)) // 跳到文件头第 10 字节之后 file.read(bytesBuf) println(Data of the 10th byte after the 10th byte: ${String.fromUtf8(bytesBuf)}) file.seek(SeekPosition.End(-10)) // 跳到文件末尾前 10 字节 file.read(bytesBuf) println(Data of the last 10 bytes: ${String.fromUtf8(bytesBuf)}) file.close() /* 以读写模式打开截断并重写文件 */ file File(filePath, ReadWrite) file.setLength(0) // 截断文件大小为 0 file.write(The file was truncated to an empty file!.toArray()) file.seek(SeekPosition.Begin(0)) let allBytes: ArrayByte readToEnd(file) file.close() println(Data written newly: ${String.fromUtf8(allBytes)}) remove(filePath) }运行结果Data of the 10th byte after the 10th byte: 123456789 Data of the last 10 bytes: abcdefghi Data written newly: The file was truncated to an empty file!该示例展示了节点流在仓颉中的完整能力用Write创建并写文件、用Append追加、用Read配合SeekPosition定位读取、用ReadWrite配合setLength截断重写最后统一close并用remove清理。String.fromUtf8用于将字节数组还原为字符串显示。小结与最佳实践回到节点流的概念本质节点流直接对接外部资源是程序与外界数据交互的第一层通道。本文覆盖的两类节点流各有适用场景标准流面向命令行交互Console封装了并发安全与缓存优化stdIn提供readln等便捷读取接口stdOut/stdErr提供丰富的write/writeln重载写入后记得flush文件流面向持久化数据fs包统一屏蔽了跨平台差异。小数据量用File.readFrom/writeTo/appendTo静态函数一次搞定大数据量或需要精细控制时用File(path, OpenMode)构造流式实例配合read/write/seek/setLength操作并通过 try-with-resource 保证资源释放。在实际项目中通常还要将节点流与处理流如BufferedInputStream、StringReader等组合使用以进一步减少磁盘 I/O 次数、提升字符串处理性能相关用法可继续阅读 I/O 处理流。赞分享文档知识库教程OpenHarmony【免费下载链接】CangjieCorpus本仓库为仓颉编程语言语料库聚焦 仓颉编程语言 核心知识体系整合官方开发指南、API 文档、典型代码示例及语法规范等多维度资源经结构化处理与专业标注构建为支持 RAG检索增强生成技术 的高质量知识基座适配智能编码助手、学习辅助工具等应用开发需求。 欢迎开发者基于本语料库构建仓颉语言智能应用推动鸿蒙开发生态智能化升级项目地址https://gitcode.com/Cangjie/CangjieCorpus点击查看免费下载相关推荐仓颉编程语言 I/O 节点流实战指南标准流与文件流仓颉编程语言 I/O 节点流实战指南标准流与文件流 节点流Node Stream是仓颉编程语言中直接连接外部数据源的流类型包括标准流标准输入/输出/错文档编程语言仓颉编程语言 I/O 节点流实战标准流与文件流的完整用法仓颉编程语言 I/O 节点流实战标准流与文件流的完整用法 节点流Node Stream是仓颉 I/O 体系中直接对接外部数据源的流类型涵盖标准流 Co文档编程语言仓颉编程语言 I/O 流全解析Stream 抽象、节点流与处理流实战指南仓颉编程语言 I/O 流全解析Stream 抽象、节点流与处理流实战指南 仓颉编程语言将所有与外部载体交互的操作抽象为基于数据流的 I/O 模型输入输出统一文档编程语言上一篇把多年的QQ空间说说一次留住GetQzonehistory一键批量导出说说、图片和评论下一篇Windows Defender恢复安全中心变灰3分钟修复创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考