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

Golang:如何遍历JSON文件并将每个对象写入单独文件

需求:CSV转JSON后拆分每个对象为独立文件

现有程序可读取CSV文件并转换为JSON格式写入单个文件,需要修改为将每个JSON对象单独写入独立文件。原代码如下:

package main

import (
    "crypto/sha256"
    "encoding/csv"
    "encoding/json"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "os"
    "strconv"
)

type NftRecord struct{
    SeriesNumber     int    `json:"Series Number"`
    Name             string `json:"Name"`
  //TheDescriptor    string `json:"The Descriptor"`
  //NewName          string `json:"New Name"`
    Hash             string `json:"Hash"`
    UUIDs            string `json:"UUIDs"`
    Description      string `json:"Description"`
    DriveLink        string `json:"Drive Link"`
}

func createRecordsList(data [][]string) []NftRecord{
    var recordList []NftRecord
    for i, line := range data{
        if i > 0{
            var rec NftRecord
            for j, field := range line{
                if j == 0{
                    var err error
                    rec.SeriesNumber, err = strconv.Atoi(field)
                    if err != nil{
                        continue
                    }
                }else if j == 4{
                    rec.Name = field
                }else if j == 7 {
                    rec.Description = field
                }else if j ==6{
                    rec.UUIDs = field
                }else if j == 5{
                    rec.Hash = field
                }else if j == 8{
                    rec.DriveLink = field
                } else if j == 13{
                    var err error 
                    if err != nil{
                        continue
                    }
                }
            }
            recordList = append(recordList, rec)
        }
    }
    return recordList
}

func main(){
    f, err := os.Open("./scaler.csv")
    if err != nil {
        log.Fatal(err)
    }

    defer f.Close()

    csvReader := csv.NewReader(f)
    data, err := csvReader.ReadAll()
    if err != nil {
        log.Fatal(err)
    }

    recordList := createRecordsList(data)

    jsonData, err := json.MarshalIndent(recordList, "", "  ")
    if err != nil {
        log.Fatal(err)
    }

    _ = ioutil.WriteFile("./test.json", jsonData, 0644)

    fmt.Println(string(jsonData))

    //hashing
    hash := sha256.New()
    if _, err := io.Copy(hash, f); err != nil {
        panic(err)
    }
    
    sum := fmt.Sprintf("%x", hash.Sum(nil))
    fmt.Println(sum)
}

修改后的代码

核心改动是遍历recordList,对每个对象单独序列化并写入文件,使用SeriesNumber作为唯一文件名标识:

package main

import (
    "crypto/sha256"
    "encoding/csv"
    "encoding/json"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "os"
    "strconv"
)

type NftRecord struct{
    SeriesNumber     int    `json:"Series Number"`
    Name             string `json:"Name"`
  //TheDescriptor    string `json:"The Descriptor"`
  //NewName          string `json:"New Name"`
    Hash             string `json:"Hash"`
    UUIDs            string `json:"UUIDs"`
    Description      string `json:"Description"`
    DriveLink        string `json:"Drive Link"`
}

func createRecordsList(data [][]string) []NftRecord{
    var recordList []NftRecord
    for i, line := range data{
        if i > 0{
            var rec NftRecord
            for j, field := range line{
                if j == 0{
                    var err error
                    rec.SeriesNumber, err = strconv.Atoi(field)
                    if err != nil{
                        log.Printf("Failed to parse Series Number for line %d: %v", i, err)
                        continue
                    }
                }else if j == 4{
                    rec.Name = field
                }else if j == 7 {
                    rec.Description = field
                }else if j ==6{
                    rec.UUIDs = field
                }else if j == 5{
                    rec.Hash = field
                }else if j == 8{
                    rec.DriveLink = field
                }
            }
            recordList = append(recordList, rec)
        }
    }
    return recordList
}

func main(){
    f, err := os.Open("./scaler.csv")
    if err != nil {
        log.Fatal(err)
    }

    defer f.Close()

    csvReader := csv.NewReader(f)
    data, err := csvReader.ReadAll()
    if err != nil {
        log.Fatal(err)
    }

    recordList := createRecordsList(data)

    // 遍历每个NftRecord,单独写入文件
    for _, rec := range recordList {
        // 序列化单个对象
        jsonData, err := json.MarshalIndent(rec, "", "  ")
        if err != nil {
            log.Printf("Failed to marshal record %d: %v", rec.SeriesNumber, err)
            continue
        }

        // 生成唯一文件名,这里用SeriesNumber保证不重复
        fileName := fmt.Sprintf("./nft_%d.json", rec.SeriesNumber)
        // 写入文件并处理错误
        err = ioutil.WriteFile(fileName, jsonData, 0644)
        if err != nil {
            log.Printf("Failed to write file %s: %v", fileName, err)
            continue
        }
        fmt.Printf("Successfully wrote file: %s\n", fileName)
    }

    // 修复哈希计算:文件读取完后指针在末尾,重置到开头才能计算正确哈希
    if _, err := f.Seek(0, io.SeekStart); err != nil {
        log.Fatal(err)
    }
    hash := sha256.New()
    if _, err := io.Copy(hash, f); err != nil {
        log.Fatal(err)
    }
    
    sum := fmt.Sprintf("%x", hash.Sum(nil))
    fmt.Printf("CSV file SHA256 hash: %s\n", sum)
}

关键说明
  1. 遍历拆分:循环处理recordList中的每个NftRecord对象,单独执行JSON序列化
  2. 唯一文件名:使用SeriesNumber作为文件名一部分确保唯一性,也可替换为UUIDs(如fmt.Sprintf("./nft_%s.json", rec.UUIDs))
  3. 错误处理优化:添加了文件写入、序列化的错误日志,避免静默失败
  4. 哈希计算修复:原代码中ReadAll已读取完文件,指针在末尾,添加f.Seek(0, io.SeekStart)重置指针,才能计算正确的CSV文件哈希

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 09:25:19