全栈应用服务器

  • 全栈应用服务器 > SDK 下载 > Go SDK 概览 > 文件管理

    文件管理

    最近更新时间: 2026-03-05 19:04:49

    文件管理

    通过 sb.Files() 进行文件读写、批量操作、目录管理和文件变更监听。

    前置条件:请先完成客户端初始化创建沙箱

    写入文件

    _, err := sb.Files().Write(ctx, "/tmp/hello.txt", []byte("Hello from Go SDK!\n"))
    if err != nil {
    	log.Fatalf("写入文件失败: %v", err)
    }
    

    Write 返回 *EntryInfo,包含写入后的文件元信息。

    读取文件

    读取为字节数组

    content, err := sb.Files().Read(ctx, "/tmp/hello.txt")
    if err != nil {
    	log.Fatalf("读取文件失败: %v", err)
    }
    fmt.Printf("文件内容: %s", string(content))
    

    读取为字符串

    text, err := sb.Files().ReadText(ctx, "/tmp/hello.txt")
    if err != nil {
    	log.Fatalf("ReadText 失败: %v", err)
    }
    fmt.Printf("文件内容: %s", text)
    

    流式读取

    适用于大文件,避免一次性加载到内存。

    rc, err := sb.Files().ReadStream(ctx, "/tmp/hello.txt")
    if err != nil {
    	log.Fatalf("ReadStream 失败: %v", err)
    }
    defer rc.Close()
    
    data, err := io.ReadAll(rc)
    if err != nil {
    	log.Fatalf("读取流失败: %v", err)
    }
    fmt.Printf("内容: %s", string(data))
    

    批量写入文件

    一次写入多个文件,减少网络往返。

    files := []sandbox.WriteEntry{
    	{Path: "/tmp/a.txt", Data: []byte("content A")},
    	{Path: "/tmp/b.txt", Data: []byte("content B")},
    	{Path: "/tmp/c.txt", Data: []byte("content C")},
    }
    infos, err := sb.Files().WriteFiles(ctx, files)
    if err != nil {
    	log.Fatalf("批量写入失败: %v", err)
    }
    for _, fi := range infos {
    	fmt.Printf("已写入: %s (%d bytes)\n", fi.Path, fi.Size)
    }
    

    目录操作

    创建目录

    _, err := sb.Files().MakeDir(ctx, "/tmp/mydir")
    if err != nil {
    	log.Fatalf("创建目录失败: %v", err)
    }
    

    列出目录内容

    entries, err := sb.Files().List(ctx, "/tmp")
    if err != nil {
    	log.Fatalf("列出目录失败: %v", err)
    }
    for _, e := range entries {
    	fmt.Printf("%s %s (%s, %d bytes)\n", e.Type, e.Name, e.Permissions, e.Size)
    }
    

    可以指定递归深度:

    entries, err := sb.Files().List(ctx, "/tmp", sandbox.WithDepth(3))
    

    文件管理操作

    检查文件是否存在

    exists, err := sb.Files().Exists(ctx, "/tmp/hello.txt")
    if err != nil {
    	log.Fatalf("Exists 失败: %v", err)
    }
    fmt.Printf("文件是否存在: %v\n", exists)
    

    获取文件信息

    info, err := sb.Files().GetInfo(ctx, "/tmp/hello.txt")
    if err != nil {
    	log.Fatalf("GetInfo 失败: %v", err)
    }
    fmt.Printf("名称: %s, 类型: %s, 大小: %d, 权限: %s\n",
    	info.Name, info.Type, info.Size, info.Permissions)
    

    EntryInfo 包含以下字段:

    字段 类型 说明
    Name string 文件名
    Type FileType 文件类型(filedirunknown
    Path string 完整路径
    Size int64 文件大小(字节)
    Mode uint32 文件模式
    Permissions string 权限字符串
    Owner string 所有者
    Group string 所属组
    ModifiedTime time.Time 修改时间
    SymlinkTarget *string 符号链接目标

    重命名文件

    renamed, err := sb.Files().Rename(ctx, "/tmp/old.txt", "/tmp/new.txt")
    if err != nil {
    	log.Fatalf("Rename 失败: %v", err)
    }
    fmt.Printf("重命名为: %s\n", renamed.Path)
    

    删除文件

    if err := sb.Files().Remove(ctx, "/tmp/hello.txt"); err != nil {
    	log.Fatalf("Remove 失败: %v", err)
    }
    

    文件系统选项

    选项 适用方法 说明
    WithUser(string) 所有文件操作 设置操作用户(默认 user
    WithDepth(uint32) List 设置递归深度(默认 1)
    WithListUser(string) List 设置列目录的用户
    WithRecursive(bool) WatchDir 是否递归监听子目录

    监听目录变更

    WatchDir 实时监听目录中的文件变更事件。

    wh, err := sb.Files().WatchDir(ctx, "/tmp/watch", sandbox.WithRecursive(true))
    if err != nil {
    	log.Fatalf("WatchDir 失败: %v", err)
    }
    
    // 接收文件变更事件
    for ev := range wh.Events() {
    	fmt.Printf("事件: type=%s, name=%s\n", ev.Type, ev.Name)
    }
    
    // 停止监听
    wh.Stop()
    if err := wh.Err(); err != nil {
    	log.Printf("监听错误: %v", err)
    }
    

    事件类型

    事件类型 说明
    create 文件或目录被创建
    write 文件被写入
    remove 文件或目录被删除
    rename 文件或目录被重命名
    chmod 文件或目录权限被修改

    超时收集事件

    wh, _ := sb.Files().WatchDir(ctx, "/tmp/watch", sandbox.WithRecursive(true))
    
    timer := time.NewTimer(3 * time.Second)
    defer timer.Stop()
    
    loop:
    for {
    	select {
    	case ev, ok := <-wh.Events():
    		if !ok {
    			break loop
    		}
    		fmt.Printf("事件: %s %s\n", ev.Type, ev.Name)
    	case <-timer.C:
    		break loop
    	}
    }
    
    wh.Stop()
    

    文件下载和上传 URL

    获取带签名的文件操作 URL,可用于浏览器直接下载/上传。

    // 下载 URL
    downloadURL := sb.DownloadURL("/tmp/hello.txt")
    fmt.Printf("下载 URL: %s\n", downloadURL)
    
    // 上传 URL(POST multipart/form-data)
    uploadURL := sb.UploadURL("/tmp/upload.txt")
    fmt.Printf("上传 URL: %s\n", uploadURL)
    

    可以指定选项:

    // 自定义用户和签名过期时间
    downloadURL := sb.DownloadURL("/tmp/hello.txt",
    	sandbox.WithFileUser("root"),
    	sandbox.WithSignatureExpiration(600), // 600 秒
    )
    

    完整示例

    package main
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"os"
    	"time"
    
    	"github.com/qiniu/go-sdk/v7/sandbox"
    )
    
    func main() {
    	c, err := sandbox.NewClient(&sandbox.Config{
    		APIKey:   os.Getenv("QINIU_API_KEY"),
    		Endpoint: os.Getenv("QINIU_SANDBOX_API_URL"),
    	})
    	if err != nil {
    		log.Fatalf("创建客户端失败: %v", err)
    	}
    
    	ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    	defer cancel()
    
    	timeout := int32(120)
    	sb, _, err := c.CreateAndWait(ctx, sandbox.CreateParams{
    		TemplateID: "base",
    		Timeout:    &timeout,
    	}, sandbox.WithPollInterval(2*time.Second))
    	if err != nil {
    		log.Fatalf("创建沙箱失败: %v", err)
    	}
    	defer sb.Kill(ctx)
    
    	// 写入文件
    	sb.Files().Write(ctx, "/tmp/hello.txt", []byte("Hello from Go SDK!\n"))
    
    	// 读取文件
    	content, _ := sb.Files().Read(ctx, "/tmp/hello.txt")
    	fmt.Printf("文件内容: %s", string(content))
    
    	// 批量写入
    	files := []sandbox.WriteEntry{
    		{Path: "/tmp/a.txt", Data: []byte("file A")},
    		{Path: "/tmp/b.txt", Data: []byte("file B")},
    	}
    	sb.Files().WriteFiles(ctx, files)
    
    	// 创建目录
    	sb.Files().MakeDir(ctx, "/tmp/mydir")
    
    	// 列出目录
    	entries, _ := sb.Files().List(ctx, "/tmp")
    	fmt.Printf("/tmp 目录: %d 项\n", len(entries))
    	for _, e := range entries {
    		fmt.Printf("  %s %s (%d bytes)\n", e.Type, e.Name, e.Size)
    	}
    
    	// 文件管理
    	exists, _ := sb.Files().Exists(ctx, "/tmp/hello.txt")
    	fmt.Printf("文件存在: %v\n", exists)
    
    	info, _ := sb.Files().GetInfo(ctx, "/tmp/hello.txt")
    	fmt.Printf("文件信息: %s %d bytes\n", info.Name, info.Size)
    
    	sb.Files().Rename(ctx, "/tmp/b.txt", "/tmp/b-renamed.txt")
    	sb.Files().Remove(ctx, "/tmp/b-renamed.txt")
    
    	// 文件 URL
    	fmt.Printf("下载 URL: %s\n", sb.DownloadURL("/tmp/hello.txt"))
    }
    
    以上内容是否对您有帮助?