You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中如何修改响应体文件压缩后的Header(含日期)

解决方案

核心问题原因

你使用archive.Create()方法时,zip包会默认采用零时间戳(对应Unix时间0),在部分时区下会显示为1979年11月30日。要修改这个时间,需要手动为每个zip内的文件设置时间戳——无需修改响应体的Header,因为io.ReadCloser类型的响应体本身不包含文件元数据(比如修改时间),这些数据要么从GET请求的响应头提取,要么直接指定当前时间。

可行方案

方案1:直接设置为当前时间

用zip.Writer.CreateHeader()替代Create(),手动构造zip.FileHeader并指定修改时间:

修改后的代码示例:

archive := zip.NewWriter(w)
attachment := "attachment; filename=someZipFile.zip"
c.Writer.Header().Set("Content-Disposition", attachment)

currentTime := time.Now() // 获取当前时间

for i := 0; i < len(bodies); i++ {
    defer bodies[i].Close()
    filePath := "someZipFile/" + filenames[i]

    // 构造自定义文件头
    fileHeader := &zip.FileHeader{
        Name:     filePath,
        Modified: currentTime,
    }
    // 设置文件权限(可选,默认0644对应普通文件读写权限)
    fileHeader.SetMode(0644)

    w, err := archive.CreateHeader(fileHeader)
    if err != nil {
        fmt.Println("File couldn't be created:", err)
        return true
    }

    if _, err := io.Copy(w, bodies[i]); err != nil {
        fmt.Println("File couldn't be written:", err)
        return true
    }
}

if err := archive.Close(); err != nil {
    fmt.Println("Failed to close zip writer:", err)
    return true
}

方案2:从GET响应头提取原文件修改时间

如果你的每个GET请求响应头包含Last-Modified字段(多数静态文件服务器会返回),需要在获取响应时保存完整的http.Response对象(而非仅Body),再解析该字段设置到zip文件头:

  1. 先调整保存响应的逻辑,比如将bodies替换为responses []*http.Response:
// 示例:发起GET请求并保存完整响应
responses := make([]*http.Response, 0)
for _, url := range downloadUrls {
    resp, err := http.Get(url)
    if err != nil {
        // 处理请求错误
        return true
    }
    responses = append(responses, resp)
}
  1. 压缩时解析Last-Modified字段:
archive := zip.NewWriter(w)
attachment := "attachment; filename=someZipFile.zip"
c.Writer.Header().Set("Content-Disposition", attachment)

for i := 0; i < len(responses); i++ {
    resp := responses[i]
    defer resp.Body.Close()
    filePath := "someZipFile/" + filenames[i]

    // 初始化文件头,默认用当前时间
    fileHeader := &zip.FileHeader{
        Name:     filePath,
        Modified: time.Now(),
    }
    fileHeader.SetMode(0644)

    // 尝试从响应头提取并解析Last-Modified
    if lastModifiedStr := resp.Header.Get("Last-Modified"); lastModifiedStr != "" {
        lastModified, err := http.ParseTime(lastModifiedStr)
        if err == nil {
            fileHeader.Modified = lastModified
        } else {
            fmt.Println("Failed to parse Last-Modified:", err)
        }
    }

    w, err := archive.CreateHeader(fileHeader)
    if err != nil {
        fmt.Println("File couldn't be created:", err)
        return true
    }

    if _, err := io.Copy(w, resp.Body); err != nil {
        fmt.Println("File couldn't be written:", err)
        return true
    }
}

if err := archive.Close(); err != nil {
    fmt.Println("Failed to close zip writer:", err)
    return true
}

关键说明

  • io.ReadCloser仅负责文件内容读取,不包含文件元数据,无需修改它的Header。
  • CreateHeader()是核心:它允许你完全控制zip内文件的元数据,包括修改时间、权限等。
  • 权限设置SetMode()是可选操作,可根据需求调整文件的读写权限。

内容的提问来源于stack exchange,提问作者ppg87

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:01:25