
作者:Undoom
日期:2025-11-03
项目:filesize - 文件大小格式化工具库
前言
本文详细记录了从零开始开发一个仓颉三方库的完整过程,包括从克隆模板、编写代码、解决问题到最终发布的每一个步骤。通过这篇文章,你将学会如何创建一个标准的、文档完善的仓颉三方库。
项目背景
在日常开发中,我们经常需要将文件大小(字节数)转换为人类可读的格式,比如将 1048576 显示为 1.05 MB。虽然这是一个简单的需求,但如果每个项目都重复实现一遍,不仅浪费时间,还容易出错。因此,我决定开发一个专门的仓颉三方库来解决这个问题。
你将学到
- ✅ 如何使用官方模板快速启动项目
- ✅ 仓颉语言的包管理和项目结构
- ✅ 遇到编译错误时如何诊断和解决
- ✅ 如何编写标准的三方库代码
- ✅ 如何完善文档和开源协议
- ✅ 如何发布到 GitCode 仓库
第一步:准备工作
1.1 环境要求
开始之前,确保你的开发环境已准备就绪:
bash
# 检查仓颉编译器版本
cjc --version
# 要求: >= 1.0.3
# 检查包管理器
cjpm --version
# 确认环境变量
echo $CANGJIE_HOME
1.2 克隆官方模板
仓颉官方提供了标准的三方库模板,可以帮助我们快速启动项目:
bash
# 克隆模板仓库
git clone git@gitcode.com:cj-awaresome/template.git filesize
cd filesize
# 查看项目结构
tree -L 2
模板的目录结构:
template/
├── README.md # 项目说明(需要修改)
├── CHANGELOG.md # 版本日志(需要修改)
├── LICENSE # 开源协议(需要修改)
├── README.OpenSource # 开源声明(需要修改)
├── cjpm.toml # 包配置(需要修改)
├── doc/ # 文档目录
│ ├── design.md # 设计文档(需要重写)
│ ├── feature_api.md # API文档(需要重写)
│ └── assets/ # 资源文件
├── src/ # 源码目录
│ └── Template.cj # 模板源码(需要替换)
└── test/ # 测试目录
├── HLT/ # 高层测试
└── LLT/ # 低层测试
第二步:配置项目基础信息
2.1 修改 cjpm.toml
这是项目的核心配置文件,需要修改为我们的库信息:
toml
[dependencies]
[package]
cjc-version = "1.0.3"
compile-option = ""
description = "文件大小格式化工具库 - 将字节数转换为人类可读的格式"
link-option = ""
name = "filesize" # 修改包名
output-type = "static" # 三方库使用 static
src-dir = ""
target-dir = ""
version = "1.0.0" # 设置版本号
package-configuration = {}
关键点:
name: 包名要与功能相关,简洁明了output-type: 三方库使用"static",不是"executable"description: 简短说明库的功能
2.2 更新远程仓库
bash
# 修改远程仓库地址
git remote set-url origin git@gitcode.com:cj-awaresome/filesize.git
# 验证修改
git remote -v
第三步:编写核心代码
3.1 创建源文件
删除模板文件,创建我们的 filesize.cj:
bash
rm src/Template.cj
touch src/filesize.cj
3.2 第一版代码实现
开始编写核心功能。这是一个迭代过程,我先写了一个基础版本:
cangjie
package filesize
import std.math.*
// 主格式化函数
public func formatFileSize(size: Int64): String {
let base = 10
let roundDigits = 2
let bits = false
let result = calculateFileSize(size, base, roundDigits, bits)
return result
}
// 核心计算逻辑
internal func calculateFileSize(size: Int64, base: Int, roundDigits: Int, bits: Bool): String {
let ceil = if (base == 10) { 1000 } else { 1024 }
let num = Float64(size)
var e: Int64 = 0
// 计算指数
if (num > 0.0) {
let logVal = log(num) / log(Float64(ceil))
let floorVal = floor(logVal)
e = Int64(floorVal)
if (e < 0) { e = 0 }
if (e > 8) { e = 8 }
}
// 计算值
var val = if (base == 2) {
num / pow(2.0, Float64(e * 10))
} else {
num / pow(1000.0, Float64(e))
}
if (bits) { val = val * 8.0 }
// 四舍五入
let factor = pow(10.0, Float64(roundDigits))
let rounded = round(val * factor) / factor
// 获取单位
let unit = getUnit(e)
return "${rounded} ${unit}"
}
// 单位映射
private func getUnit(exponent: Int64): String {
if (exponent == 0) { return "B" }
if (exponent == 1) { return "KB" }
if (exponent == 2) { return "MB" }
if (exponent == 3) { return "GB" }
if (exponent == 4) { return "TB" }
if (exponent == 5) { return "PB" }
if (exponent == 6) { return "EB" }
if (exponent == 7) { return "ZB" }
if (exponent == 8) { return "YB" }
return "B"
}
3.3 第一次编译 - 遇到问题!
bash
cjpm build
错误信息:
Error: the package name in /Users/jianguo/Desktop/cangjie/tpc/template-1/src is wrong,
the right name should be 'filesize'
问题分析 :
这是仓颉语言的一个重要特性 - 每个源文件都必须声明它所属的包!我在文件开头添加了 package filesize,但编译器还在报错。
经过排查,发现还有其他文件(constants.cj、types.cj)也缺少包声明。
解决方案 :
确保所有 .cj 文件的第一行都是包声明:
cangjie
package filesize
// 其他代码...
3.4 第二个问题 - 导入不存在的模块
错误信息:
Error: root package 'filesize' imports package 'std.string' in its source code,
but it is not added as a dependency in cjpm.toml
问题分析 :
我引用了 std.string.*,但实际上仓颉标准库中并不存在这个模块!
解决方案 :
删除不存在的导入:
cangjie
package filesize
import std.math.*
// import std.string.* ❌ 删除这一行
3.5 第三个问题 - 语法兼容性
在开发过程中,我发现我最初写的一些语法在仓颉中不支持:
问题 1:默认参数
cangjie
// ❌ 错误:仓颉不支持默认参数
public func formatFileSize(size: Int64, options: Map<String, Any> = {}): String
// ✅ 正确:使用函数重载或固定参数
public func formatFileSize(size: Int64): String
问题 2:三元运算符
cangjie
// ❌ 错误:不支持 ? : 语法
let ceil = base == 10 ? 1000 : 1024
// ✅ 正确:使用 if 表达式
let ceil = if (base == 10) { 1000 } else { 1024 }
问题 3:类型转换方法
cangjie
// ❌ 错误:方法名不对
let num = size.toFloat64()
// ✅ 正确:使用类型构造函数
let num = Float64(size)
3.6 成功编译!
修复所有问题后:
bash
cjpm build
# 输出:cjpm build success ✅
第四步:编写测试用例
4.1 创建测试文件
bash
rm -rf test/HLT test/LLT
touch test/test.cj
4.2 编写测试代码
cangjie
package filesize.test
import filesize.*
test "格式化 1KB" {
let result = formatFileSize(1024)
println("1024 bytes = ${result}")
assert(result.contains("KB"))
}
test "格式化 1MB" {
let result = formatFileSize(1024 * 1024)
println("1MB = ${result}")
assert(result.contains("MB"))
}
test "格式化 1GB" {
let result = formatFileSize(1024 * 1024 * 1024)
println("1GB = ${result}")
assert(result.contains("GB"))
}
4.3 运行测试
bash
cjpm test
# 输出:cjpm test success ✅
第五步:完善项目文档
5.1 编写 LICENSE
采用 Apache 2.0 开源协议:
bash
# 创建完整的 Apache 2.0 协议文件
# 并在文件头部添加版权声明
Apache License
Version 2.0, January 2004
Copyright 2025 坚果 (Jianguo)
Licensed under the Apache License, Version 2.0...
5.2 更新 README.md
编写专业的项目说明文档,包括:
markdown
# filesize - 文件大小格式化库
## 介绍
简要说明库的功能...
## 项目特性
- ✨ 简单易用
- 📊 自动单位转换
...
## 使用说明
### 安装
### 使用示例
## 开源协议
Apache License 2.0
5.3 编写 CHANGELOG.md
记录版本历史:
markdown
# 更新日志
## [1.0.0] - 2025-11-03
### Feature
+ 实现文件大小格式化核心功能
+ 支持 KB、MB、GB 等单位自动转换
...
5.4 编写技术文档
doc/design.md - 设计文档:
- 架构设计
- 算法说明
- 数据流程
- 性能分析
doc/feature_api.md - API 文档:
- 函数签名
- 参数说明
- 使用示例
- 注意事项
5.5 更新 README.OpenSource
json
[
{
"Name": "filesize",
"License": "Apache License 2.0",
"License File": "LICENSE",
"Version": "1.0.0",
"Owner": "jianguo@nutpi.net",
"Upstream URL": "https://gitcode.com/cj-awaresome/filesize",
"Description": "仓颉语言的文件大小格式化工具库"
}
]
5.6 添加 .gitignore
bash
# 创建 .gitignore 文件
cat > .gitignore << 'EOF'
# 编译输出
target/
cjpm.lock
# IDE 配置
.vscode/
.idea/
*.swp
# 系统文件
.DS_Store
EOF
第六步:提交到 Git 仓库
6.1 添加所有文件
bash
git add -A
git status
查看待提交的文件:
Changes to be committed:
new file: .gitignore
modified: CHANGELOG.md
modified: LICENSE
modified: README.OpenSource
modified: README.md
modified: cjpm.toml
deleted: src/Template.cj
new file: src/filesize.cj
modified: doc/design.md
modified: doc/feature_api.md
deleted: test/HLT/testcase0001.cj
deleted: test/LLT/testcase0001.cj
new file: test/test.cj
6.2 提交代码
bash
git commit -m "实现 filesize 库:文件大小格式化工具
- 添加 filesize.cj 实现文件大小格式化功能
- 支持 KB, MB, GB 等单位自动转换
- 更新 cjpm.toml 配置,包名改为 filesize
- 添加基础测试用例
- 完善所有文档和开源协议
- 删除模板文件,添加 .gitignore"
6.3 推送到远程仓库
bash
git push origin main
输出:
remote: Start Git Hooks Checking [PASSED]
To gitcode.com:cj-awaresome/filesize.git
* [new branch] main -> main
成功!🎉
第七步:后续优化
7.1 修复编译警告
第一次运行时发现有未使用变量的警告:
warning: unused variable:'standard'
解决方案:删除未使用的参数
bash
git commit -m "修复编译警告,移除未使用的参数"
git push origin main
7.2 移除 main() 函数
三方库不应该包含可执行入口:
cangjie
// ❌ 删除 main() 函数
main() {
println("Testing...")
}
bash
git commit -m "完善三方库配置 - 移除 main() 函数"
git push origin main
开发过程中的经验总结
🎯 关键要点
-
包声明必不可少
- 每个
.cj文件必须以package 包名开头 - 包名要与
cjpm.toml中的name一致
- 每个
-
注意语法差异
- 仓颉不支持默认参数
- 使用
if (condition) { value } else { value }而不是三元运算符 - 类型转换使用构造函数:
Float64(value)
-
三方库的特殊要求
output-type必须是"static"- 不应包含
main()函数 - 专注于提供可复用的功能
-
标准库的使用
- 仔细检查标准库模块是否存在
- 数学函数在
std.math.* - 不存在
std.string.*模块
🐛 常见错误及解决方案
| 错误 | 原因 | 解决方案 |
|---|---|---|
| package name is wrong | 缺少包声明 | 添加 package 包名 |
| imports package 'std.xxx' but not in dependencies | 模块不存在或未声明依赖 | 检查模块是否存在 |
| expected ',' or ')' | 语法错误(如默认参数) | 使用仓颉支持的语法 |
| undeclared identifier | 类型转换方法错误 | 使用类型构造函数 |
💡 最佳实践
-
从简单开始
- 先实现核心功能
- 验证编译通过
- 再逐步添加特性
-
及时测试
- 每次修改后立即编译
- 写简单的测试验证功能
- 不要等到最后才测试
-
文档同步
- 代码和文档同步更新
- 提供实际可运行的示例
- 说明清楚每个 API 的用途
-
版本管理
- 使用有意义的提交信息
- 一个功能一次提交
- 保持提交历史清晰
项目成果
经过几个小时的开发,我们完成了一个标准的仓颉三方库:
📦 项目统计
- 源码文件 : 1 个(
filesize.cj,64 行) - 测试文件 : 1 个(
test.cj,22 行) - 文档文件: 6 个(README、CHANGELOG、LICENSE、设计文档、API文档等)
- 总代码行数: ~800 行(含文档)
✅ 完成的功能
- 文件大小格式化(B 到 YB)
- 自动单位选择
- 精度控制(2位小数)
- 单元测试
- 完整文档
- 开源协议
🚀 如何使用
其他开发者可以这样使用我们的库:
cangjie
// 在 cjpm.toml 中添加依赖
[dependencies.filesize]
git = "git@gitcode.com:cj-awaresome/filesize.git"
// 在代码中使用
import filesize.*
main() {
let size = formatFileSize(1048576)
println(size) // 输出: 1.05 MB
}
未来展望
v1.1.0 计划
- 支持配置选项
- 二进制(1024)和十进制(1000)切换
- 自定义小数位数
v1.2.0 计划
- 支持 bits 显示模式
- IEC 和 JEDEC 标准支持
- 国际化支持
结语
从零开始开发一个仓颉三方库并不难,关键是要:
- 熟悉工具链 - 理解 cjpm 的工作方式
- 注意细节 - 包声明、语法规范等
- 完善文档 - 好的文档是优秀库的标志
- 持续迭代 - 从简单开始,逐步完善
希望这篇文章能帮助更多开发者参与到仓颉生态建设中来。如果你也想开发自己的三方库,不妨从这个模板开始,创造属于你的优秀作品!
相关资源
- 项目地址: https://gitcode.com/cj-awaresome/filesize
- 官方模板: https://gitcode.com/cj-awaresome/template
- 仓颉文档: https://gitcode.com/Cangjie
- 作者联系: jianguo@nutpi.net
作者 : Undoom
项目 : filesize v1.0.0
日期 : 2025-11-03
协议: Apache License 2.0