POSIX API 使用
Kotlin/Native 预置了完整的 POSIX API 绑定,可直接调用系统底层功能。本文介绍常用 POSIX API 的使用。
文件操作
基础文件 I/O
kotlin
@OptIn(ExperimentalForeignApi::class)
import platform.posix.*
fun readFile(path: String): String? {
val file = fopen(path, "r") ?: return null
try {
memScoped {
val buffer = allocArray<ByteVar>(4096)
val content = buildString {
while (true) {
val line = fgets(buffer, 4096, file) ?: break
append(line.toKString())
}
}
return content
}
} finally {
fclose(file)
}
}
fun writeFile(path: String, content: String): Boolean {
val file = fopen(path, "w") ?: return false
try {
content.cstr.use { cStr ->
fputs(cStr.ptr, file)
}
return true
} finally {
fclose(file)
}
}文件描述符操作
kotlin
@OptIn(ExperimentalForeignApi::class)
fun lowLevelFileIO() {
// 打开文件
val fd = open("/tmp/test.txt", O_RDWR or O_CREAT, 0x644)
if (fd < 0) {
perror("open failed")
return
}
try {
// 写入数据
val data = "Hello, POSIX!".cstr
write(fd, data.ptr, data.size.toULong())
// 移动文件指针
lseek(fd, 0, SEEK_SET)
// 读取数据
memScoped {
val buffer = allocArray<ByteVar>(100)
val bytesRead = read(fd, buffer, 100u)
println("Read: ${buffer.toKString()}")
}
} finally {
close(fd)
}
}进程管理
创建子进程
kotlin
@OptIn(ExperimentalForeignApi::class)
fun executeCommand(command: String): Int {
val pid = fork()
when {
pid < 0 -> {
// Fork 失败
perror("fork failed")
return -1
}
pid == 0 -> {
// 子进程
execlp("/bin/sh", "sh", "-c", command, null)
// 如果 exec 返回,说明失败
perror("exec failed")
exit(1)
}
else -> {
// 父进程,等待子进程
memScoped {
val status = alloc<IntVar>()
waitpid(pid, status.ptr, 0)
return WEXITSTATUS(status.value)
}
}
}
return 0
}环境变量
kotlin
@OptIn(ExperimentalForeignApi::class)
fun environmentVariables() {
// 获取环境变量
val home = getenv("HOME")?.toKString()
println("HOME: $home")
// 设置环境变量
setenv("MY_VAR", "value", 1)
// 删除环境变量
unsetenv("MY_VAR")
}目录操作
遍历目录
kotlin
@OptIn(ExperimentalForeignApi::class)
fun listDirectory(path: String): List<String> {
val dir = opendir(path) ?: return emptyList()
val files = mutableListOf<String>()
try {
while (true) {
val entry = readdir(dir) ?: break
val name = entry.pointed.d_name.toKString()
if (name != "." && name != "..") {
files.add(name)
}
}
} finally {
closedir(dir)
}
return files
}文件状态
kotlin
@OptIn(ExperimentalForeignApi::class)
fun getFileInfo(path: String) {
memScoped {
val statBuf = alloc<stat>()
if (stat(path, statBuf.ptr) == 0) {
println("Size: ${statBuf.st_size}")
println("Mode: ${statBuf.st_mode.toString(8)}")
println("UID: ${statBuf.st_uid}")
println("GID: ${statBuf.st_gid}")
// 检查文件类型
when {
S_ISREG(statBuf.st_mode.toUInt()) -> println("Regular file")
S_ISDIR(statBuf.st_mode.toUInt()) -> println("Directory")
S_ISLNK(statBuf.st_mode.toUInt()) -> println("Symbolic link")
}
}
}
}网络编程
Socket 基础
kotlin
@OptIn(ExperimentalForeignApi::class)
fun createTcpSocket(): Int {
return socket(AF_INET, SOCK_STREAM, 0)
}
fun connectToServer(host: String, port: Int): Int {
val sockfd = createTcpSocket()
if (sockfd < 0) return -1
memScoped {
val addr = alloc<sockaddr_in>()
addr.sin_family = AF_INET.toUShort()
addr.sin_port = htons(port.toUShort())
// 解析主机名
inet_pton(AF_INET, host, addr.sin_addr.ptr)
val result = connect(
sockfd,
addr.ptr.reinterpret(),
sizeOf<sockaddr_in>().toUInt()
)
if (result < 0) {
close(sockfd)
return -1
}
}
return sockfd
}时间处理
时间戳与格式化
kotlin
@OptIn(ExperimentalForeignApi::class)
fun timeOperations() {
// 获取当前时间戳
val now = time(null)
println("Unix timestamp: $now")
// 转换为本地时间
memScoped {
val tm = localtime(cValuesOf(now))?.pointed
tm?.let {
println("Year: ${it.tm_year + 1900}")
println("Month: ${it.tm_mon + 1}")
println("Day: ${it.tm_mday}")
println("Hour: ${it.tm_hour}")
}
// 格式化时间
val buffer = allocArray<ByteVar>(100)
strftime(buffer, 100u, "%Y-%m-%d %H:%M:%S", tm)
println(buffer.toKString())
}
}信号处理
注册信号处理器
kotlin
@OptIn(ExperimentalForeignApi::class)
val signalHandler = staticCFunction<Int, Unit> { sig ->
println("Received signal: $sig")
}
fun setupSignals() {
signal(SIGINT, signalHandler)
signal(SIGTERM, signalHandler)
}POSIX API 提供了强大的系统级编程能力,是实现跨平台 Native 应用的基础。