基础I/O操作
I/O(输入/输出)操作是程序与外部世界交互的基础。本章将详细介绍 Sii 2 中的文件操作、标准输入输出、环境变量等 I/O 功能。
I/O 操作概述
Sii 2 通过不同的命名空间提供 I/O 操作功能:
- 标准输入输出:通过
sii.io命名空间(sii.io.print(),sii.io.readLine()等) - 文件操作:通过
sii命名空间(sii.readText(),sii.writeText()等) - 目录操作:通过
sii命名空间(sii.mkdirs(),sii.pathJoin()等) - 环境变量:通过
sii命名空间(sii.env())
标准输入输出
输出操作
sii.io.print()
print() 函数用于向标准输出打印内容:
// 打印字符串
sii.io.print("Hello, World!");
// 打印变量
let name: string = "Alice";
sii.io.print(name);
// 打印多个值(通过字符串拼接)
let age: int = 25;
sii.io.print("Name: " + name + ", Age: " + string(age));
格式化输出
let name: string = "Bob";
let score: int = 95;
let percentage: singlef = 95.5;
// 基本格式化
sii.io.print("Student: " + name);
sii.io.print("Score: " + string(score));
sii.io.print("Percentage: " + string(percentage));
输入操作
Sii 2 提供了多种输入函数来获取用户输入:
sii.io.readLine()
读取一行字符串输入:
// 获取字符串输入
let name: string = sii.io.readLine();
sii.io.print("Hello, " + name + "!");
sii.io.readInt()
读取整数输入:
// 获取整数输入
let age: int = sii.io.readInt();
sii.io.print("Age: " + string(age));
sii.io.readSinglef()
读取单精度浮点数输入:
// 获取单精度浮点数输入
let price: singlef = sii.io.readSinglef();
sii.io.print("Price: " + string(price));
sii.io.readMultif()
读取多精度浮点数输入:
// 获取多精度浮点数输入
let value: multif = sii.io.readMultif();
sii.io.print("Value: " + string(value));
输入函数说明
sii.io.readLine()- 返回string类型sii.io.readInt()- 返回int类型sii.io.readSinglef()- 返回singlef类型sii.io.readMultif()- 返回multif类型
文件操作
读取文件
sii.readText()
读取文本文件内容:
// 读取文件
let content: string = sii.readText("./data.txt");
sii.io.print("File content: " + content);
错误处理
func readFileSafely(path: string): string | void {
if (!sii.exists(path)) {
sii.io.print("Error: File not found: " + path);
back;
}
back sii.readText(path);
}
// 使用
let content: string | void = readFileSafely("./config.json");
if (typeins(content) == "string") {
let text: string = content as string;
sii.io.print(text);
}
写入文件
sii.writeText()
将内容写入文件:
// 写入文件
sii.writeText("./output.txt", "Hello, Sii 2!");
// 写入多行内容
let content: string = "Line 1\nLine 2\nLine 3";
sii.writeText("./multiline.txt", content);
自动创建目录
writeText() 会自动创建不存在的父目录:
// 如果 ./logs/ 不存在,会自动创建
sii.writeText("./logs/app.log", "Log message");
检查文件存在
sii.exists()
检查文件或目录是否存在:
let filePath: string = "./data.txt";
if (sii.exists(filePath)) {
sii.io.print("File exists");
let content: string = sii.readText(filePath);
} else {
sii.io.print("File does not exist");
}
目录操作
sii.mkdirs()
创建目录(包括所有父目录):
// 创建单个目录
sii.mkdirs("./logs");
// 创建嵌套目录
sii.mkdirs("./data/2024/12");
检查目录存在
let dirPath: string = "./data";
if (!sii.exists(dirPath)) {
sii.mkdirs(dirPath);
sii.io.print("Directory created");
}
路径操作
sii.pathJoin()
拼接路径:
// 拼接路径
let basePath: string = "./data";
let fileName: string = "config.json";
let fullPath: string = sii.pathJoin(basePath, fileName);
// 结果: ./data/config.json
// 多级路径
let path1: string = "/usr";
let path2: string = "local";
let path3: string = "bin";
let fullPath: string = sii.pathJoin(sii.pathJoin(path1, path2), path3);
// 结果: /usr/local/bin
sii.cwd()
获取当前工作目录:
let currentDir: string = sii.cwd();
sii.io.print("Current directory: " + currentDir);
环境变量
sii.env()
读取环境变量:
// 读取环境变量
let homeDir: string = sii.env("HOME");
let path: string = sii.env("PATH");
let user: string = sii.env("USER");
sii.io.print("Home directory: " + homeDir);
sii.io.print("User: " + user);
环境变量使用示例
func getConfigPath(): string {
let configDir: string = sii.env("CONFIG_DIR");
if (configDir.length() == 0) {
configDir = "./config"; // 默认值
}
back sii.pathJoin(configDir, "app.json");
}
JSON 操作
sii.jsonParse()
解析 JSON 字符串:
let jsonString: string = '{"name": "Alice", "age": 25}';
let data: obj = sii.jsonParse(jsonString);
// 访问解析后的数据
let name: string = data.name;
let age: int = data.age;
sii.jsonStringify()
将对象转换为 JSON 字符串:
crob person = new Object();
person.name = "Bob";
person.age = 30;
let jsonString: string = sii.jsonStringify(person);
sii.io.print(jsonString);
// 输出: {"name":"Bob","age":30}
文件操作完整示例
示例 1:配置文件读写
func loadConfig(): obj | void {
let configPath: string = "./config.json";
if (!sii.exists(configPath)) {
sii.warn("Config file not found, creating default");
crob defaultConfig = new Object();
defaultConfig.host = "localhost";
defaultConfig.port = 8080;
defaultConfig.debug = false;
let jsonString: string = sii.jsonStringify(defaultConfig);
sii.writeText(configPath, jsonString);
back defaultConfig;
}
let content: string = sii.readText(configPath);
let config: obj = sii.jsonParse(content);
back config;
}
func saveConfig(config: obj): void {
let configPath: string = "./config.json";
let jsonString: string = sii.jsonStringify(config);
sii.writeText(configPath, jsonString);
sii.io.print("Config saved");
}
示例 2:日志系统
func writeLog(message: string): void {
let logDir: string = "./logs";
if (!sii.exists(logDir)) {
sii.mkdirs(logDir);
}
let timestamp: string = string(sii.now());
let logFile: string = sii.pathJoin(logDir, "app.log");
let logEntry: string = "[" + timestamp + "] " + message + "\n";
// 追加到日志文件(简化版,实际可能需要读取后追加)
let existingContent: string = if (sii.exists(logFile)) { sii.readText(logFile) } else { "" };
let newContent: string = existingContent + logEntry;
sii.writeText(logFile, newContent);
}
示例 3:文件复制
func copyFile(sourcePath: string, destPath: string): bool {
// 检查源文件
if (!sii.exists(sourcePath)) {
sii.error("Source file not found: " + sourcePath);
back false;
}
// 读取源文件
let content: string = sii.readText(sourcePath);
// 确保目标目录存在
let destDir: string = sii.pathJoin(destPath, "..");
if (!sii.exists(destDir)) {
sii.mkdirs(destDir);
}
// 写入目标文件
sii.writeText(destPath, content);
// 验证复制
if (sii.exists(destPath)) {
sii.log("File copied successfully");
back true;
} else {
sii.error("Failed to copy file");
back false;
}
}
I/O 操作最佳实践
1. 错误处理
始终检查文件操作是否成功:
func safeReadFile(path: string): string | void {
if (!sii.exists(path)) {
sii.error("File not found: " + path);
back;
}
let content: string = sii.readText(path);
back content;
}
2. 路径处理
使用 pathJoin() 而不是字符串拼接:
// 好的做法
let path: string = sii.pathJoin("./data", "config.json");
// 不好的做法
let path: string = "./data" + "/" + "config.json"; // 跨平台可能有问题
3. 资源管理
及时处理文件,避免资源泄漏:
func processFile(path: string): void {
let content: string = sii.readText(path);
// 立即处理内容
processContent(content);
// 不需要显式关闭,Sii 2 会自动管理
}
4. 大文件处理
对于大文件,考虑分块处理:
// 注意:Sii 2 的 readText 可能一次性读取整个文件
// 对于大文件,可能需要其他处理方式
func processLargeFile(path: string): void {
let content: string = sii.readText(path);
// 处理内容...
}
跨平台注意事项
路径分隔符
不同操作系统使用不同的路径分隔符:
- Windows:
\ - Unix/Linux/macOS:
/
使用 pathJoin() 可以自动处理这些差异。
文件权限
在某些系统上,文件权限可能影响操作:
func checkFileAccess(path: string): bool {
if (!sii.exists(path)) {
back false;
}
// 尝试读取以检查权限
let content: string = sii.readText(path);
back true;
}
小结
本章介绍了 Sii 2 中的基础 I/O 操作:
- 标准输入输出:
sii.io.print(),sii.io.readLine(),sii.io.readInt()等 - 文件操作:
sii.readText(),sii.writeText(),sii.exists() - 目录操作:
sii.mkdirs(),sii.pathJoin(),sii.cwd() - 环境变量:
sii.env() - JSON 操作:
sii.jsonParse(),sii.jsonStringify() - 最佳实践:错误处理、路径处理、资源管理
下一章我们将学习网络编程,了解如何构建 HTTP 客户端和服务器。