I/O Node Streams
Inspect one language lane at a time so line-level text and code deltas stay readable.
Diff Lane
English
0 modified sections0 code block delta0 anchor delta
Diff Lane
中文
2 modified sections0 code block delta0 anchor delta
modified标准流text+1 line
v1.0.5
Section Text
1
标准流包含标准输入流、标准输出流和标准错误输出流。2
3
标准流是程序与外部数据交互的标准接口。程序运行的时候从输入流读取数据,作为程序的输入,程序运行过程中输出的信息被传送到输出流,类似的,错误信息被传送到错误流。4
5
在仓颉编程语言中可以使用 `getStdIn`、`getStdOut`、`getStdErr` 全局函数来分别获取这三个标准流。6
7
使用上面的函数需要导入 `env` 包:8
9
导入 env 包示例:10
11
<!-- run -->12
13
14
`env` 包内的 `ConsoleReader` 和 `ConsoleWriter` 类型对这三个标准流都进行了易用性封装(标准错误输出流也是输出流,所以一共是两个类型),提供了更方便的基于 `String` 的扩展操作,并且对于很多常见类型都提供了丰富的重载来优化性能。15
16
其中最重要的是 `ConsoleReader` 和 `ConsoleWriter` 类型提供了并发安全的保证,可以在任意线程中安全地通过该类型提供的接口来读写内容。17
18
默认情况下标准输入流来源于键盘输入的信息,例如在命令行界面中输入的文本。19
20
当需要从标准输入流中获取数据时,可以通过 `getStdIn` 全局函数获取 `ConsoleReader` 类型,再通过该类型的 `readln` 函数获取命令行的输入。21
22
标准输入流读取示例:23
24
<!-- run -->25
26
27
运行上面的代码,在命令行上输入一些文字,然后换行结束,即可看到输入的内容。28
29
输出流分为标准输出流和标准错误流,默认情况下,它们都会输出到屏幕,例如在命令行界面中看到的文本。30
31
当需要往标准输出流中写入数据时,可以通过 `getStdOut`/`getStdErr` 全局函数获取 `ConsoleWriter` 来写入,例如通过 `write` 函数来向控制台打印内容。32
33
使用 `ConsoleWriter` 和直接使用 `print` 函数的差别是,`ConsoleWriter` 是并发安全的,并且由于 `ConsoleWriter` 使用了缓存技术,在输入内容较多时拥有更好的性能表现。34
35
需要注意的是,写完数据后需要对 `ConsoleWriter` 调用 `flush` 才能保证内容被完整写到标准流中。36
37
标准输出流写入示例:38
39
<!-- run -->Code 1 · cangjie
1
import std.env.*Code 2 · cangjie
1
import std.env.getStdIn2
3
main() {4
let consoleReader = getStdIn()5
let txt = consoleReader.readln()6
println(txt ?? "")7
}Code 3 · cangjie
1
import std.env.getStdOut2
3
main() {4
let consoleWriter = getStdOut()5
for (_ in 0..1000) {6
consoleWriter.writeln("hello, world!")7
}8
consoleWriter.flush()9
}v1.1.0
Section Text
1
标准流包含标准输入流、标准输出流和标准错误输出流。2
3
标准流是程序与外部数据交互的标准接口。程序运行的时候从输入流读取数据,作为程序的输入,程序运行过程中输出的信息被传送到输出流,类似的,错误信息被传送到错误流。4
5
在仓颉编程语言中可以使用 `getStdIn`、`getStdOut`、`getStdErr` 全局函数来分别获取这三个标准流。6
7
使用上面的函数需要导入 `env` 包:8
9
导入 env 包示例:10
11
<!-- run -->12
13
14
`env` 包内的 `ConsoleReader` 和 `ConsoleWriter` 类型对这三个标准流都进行了易用性封装(标准错误输出流也是输出流,所以一共是两个类型),提供了更方便的基于 `String` 的扩展操作,并且对于很多常见类型都提供了丰富的重载来优化性能。15
16
其中最重要的是 `ConsoleReader` 和 `ConsoleWriter` 类型提供了并发安全的保证,可以在任意线程中安全地通过该类型提供的接口来读写内容。17
18
默认情况下标准输入流来源于键盘输入的信息,例如在命令行界面中输入的文本。19
20
当需要从标准输入流中获取数据时,可以通过 `getStdIn` 全局函数获取 `ConsoleReader` 类型,再通过该类型的 `readln` 函数获取命令行的输入。21
22
标准输入流读取示例:23
24
<!-- compile -->25
26
27
运行上面的代码,在命令行上输入一些文字,然后换行结束,即可看到输入的内容。28
29
输出流分为标准输出流和标准错误流,默认情况下,它们都会输出到屏幕,例如在命令行界面中看到的文本。30
31
当需要往标准输出流中写入数据时,可以通过 `getStdOut`/`getStdErr` 全局函数获取 `ConsoleWriter` 来写入,例如通过 `write` 函数来向控制台打印内容。32
33
使用 `ConsoleWriter` 和直接使用 `print` 函数的差别是,`ConsoleWriter` 是并发安全的,并且由于 `ConsoleWriter` 使用了缓存技术,在输入内容较多时拥有更好的性能表现。34
35
需要注意的是,写完数据后需要对 `ConsoleWriter` 调用 `flush` 才能保证内容被完整写到标准流中。36
37
标准输出流写入示例:38
39
<!-- run -->Code 1 · cangjie
1
import std.env.*Code 2 · cangjie
1
import std.env.getStdIn2
3
main() {4
let consoleReader = getStdIn()5
let txt = consoleReader.readln()6
println(txt ?? "")7
}Code 3 · cangjie
1
import std.env.getStdOut2
3
main() {4
let consoleWriter = getStdOut()5
for (_ in 0..1000) {6
consoleWriter.writeln("hello, world!")7
}8
consoleWriter.flush()9
}modified文件流操作textcode+2 lines
v1.0.5
Section Text
1
除了上述的常规文件操作之外,`File` 类型也被设计为一种数据流类型,因此 `File` 类型本身实现了 `IOStream` 接口。当创建了一个 `File` 的实例,可以把这个实例当成数据流来使用。2
3
File 类定义:4
5
6
`File` 提供了两种构造方式,一种是通过方便的静态函数 `create` 直接创建新文件的实例,另一种是通过构造函数传入完整的打开文件模式来构造新实例。7
8
其中 `create` 创建的文件是只写的,不能对实例进行读操作,否则会抛出运行时异常。9
10
File 构造示例:11
12
<!-- compile -->13
14
15
当需要更精细的打开模式时,可以使用构造函数传入一个 `OpenMode` 值。`OpenMode` 是一个 `enum` 类型,它提供了丰富的文件打开模式,包含 `Read`、`Write`、`Append` 和 `ReadWrite` 模式。16
17
File 打开模式使用示例:18
19
20
因为打开 `File` 的实例会占用宝贵的系统资源,所以使用完 `File` 的实例之后需要注意及时关闭 `File`,以释放系统资源。21
22
`File` 实现了 `Resource` 接口,在大多数时候都可以使用 try-with-resource 语法来简化使用。23
24
try-with-resource 语法使用示例:Code 1 · cangjie
1
public class File <: Resource & IOStream & Seekable {2
...3
}Code 2 · cangjie
1
// 创建2
internal import std.fs.*3
internal import std.io.*4
5
main() {6
let file = File.create("./tempFile.txt")7
file.write("hello, world!".toArray())8
9
// 打开10
let file2 = File("./tempFile.txt", Read)11
let bytes = readToEnd(file2) // 读取所有数据12
println(bytes)13
}Code 3 · cangjie
1
// 使用指定选项打开模式2
let file = File("./tempFile.txt", Write)Code 4 · cangjie
1
try (file2 = File("./tempFile.txt", Read)) {2
...3
// 结束使用后自动释放文件4
}v1.1.0
Section Text
1
除了上述的常规文件操作之外,`File` 类型也被设计为一种数据流类型,因此 `File` 类型本身实现了 `IOStream` 接口。当创建了一个 `File` 的实例,可以把这个实例当成数据流来使用。2
3
File 类定义:4
5
<!-- code_no_check -->6
7
`File` 提供了两种构造方式,一种是通过方便的静态函数 `create` 直接创建新文件的实例,另一种是通过构造函数传入完整的打开文件模式来构造新实例。8
9
其中 `create` 创建的文件是只写的,不能对实例进行读操作,否则会抛出运行时异常。10
11
File 构造示例:12
13
<!-- compile -->14
15
16
当需要更精细的打开模式时,可以使用构造函数传入一个 `OpenMode` 值。`OpenMode` 是一个 `enum` 类型,它提供了丰富的文件打开模式,包含 `Read`、`Write`、`Append` 和 `ReadWrite` 模式。17
18
File 打开模式使用示例:19
20
<!-- run -->21
22
23
因为打开 `File` 的实例会占用宝贵的系统资源,所以使用完 `File` 的实例之后需要注意及时关闭 `File`,以释放系统资源。24
25
`File` 实现了 `Resource` 接口,在大多数时候都可以使用 try-with-resource 语法来简化使用。26
27
try-with-resource 语法使用示例:28
29
<!-- run -->Code 1 · cangjie
1
public class File <: Resource & IOStream & Seekable {2
...3
}Code 2 · cangjie
1
// 创建2
internal import std.fs.*3
internal import std.io.*4
5
main() {6
let file = File.create("./tempFile.txt")7
file.write("hello, world!".toArray())8
9
// 打开10
let file2 = File("./tempFile.txt", Read)11
let bytes = readToEnd(file2) // 读取所有数据12
println(bytes)13
}Code 3 · cangjie
1
// 使用指定选项打开模式2
let file = File("./tempFile.txt", Write)Code 4 · cangjie
1
try (file2 = File("./tempFile.txt", Read)) {2
// ...3
// 结束使用后自动释放文件4
}