使用golang写入文件字节进行优化

时间:2018-10-10 14:43:09

标签: arrays file go byte

我有以下程序可以在ng serve // with live reload on port 4200 ng serve --live-reload=false --port=4300 // without live reload on port 4300 文件中打印出有关每个证书的信息:

.pem

它可以工作,但是请注意,每一行都分别写入文件。这似乎有点浪费,但是我对Go中的选项不清楚...我创建一个数组...我从证书中对其进行切片...另一个用于循环...

问题

代替每行中的f.Write(),Go中正确或替代的方法是什么?

我应该使用该数据而不是使用cert。*捕获数据到结构或数组中吗?

关注

假设最后一次写入或任何写入失败,Go会回滚更改还是最后一次写入未写入文件?这需要全部写入或不写入。

(这是我的学习方式,谢谢您的帮助)

1 个答案:

答案 0 :(得分:0)

写到内存中缓冲区的最简单方法是使用bytes包,该包提供了Buffer类型。由于Buffer实现了the Writer interface,因此您可以将Write调用更新为使用Buffer,然后使用Buffer.WriteTo方法将累积的数据写出到文件。这是看起来像的样子,同时还结合了循环:

package main

import (
    "bytes"
    "crypto/x509"
    "encoding/pem"
    "io/ioutil"
    "log"
    "os"
    "strconv"
)

func main() {
    //for dev purposes set to 256
    const SignatureLength int = 256

    certPEMBlock, err := ioutil.ReadFile("testsign.crt")
    if err != nil {
        log.Fatal(err)
    }

    //OPEN FILE TO APPEND CERT INFORMATION INTO
    f, err := os.OpenFile("appendMe.txt", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
    if err != nil {
        log.Fatal(err)
    }

    var buf bytes.Buffer
    for {
        var certDERBlock *pem.Block
        certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
        if certDERBlock == nil {
            break
        }

        if certDERBlock.Type == "CERTIFICATE" {
            cert, err := x509.ParseCertificate(certDERBlock.Bytes)
            if err != nil {
                log.Println(err)
                continue
            }

            //APPEND CERT INFO TO FILE
            //VERSION
            if _, err := buf.Write([]byte(strconv.Itoa(cert.Version))); err != nil {
                log.Fatal(err)
            }
            //KEY ID
            if _, err := buf.Write(cert.SubjectKeyId); err != nil {
                log.Fatal(err)
            }
            //SIGNATURE LENGTH
            if _, err := buf.Write([]byte(strconv.Itoa(SignatureLength))); err != nil {
                log.Fatal(err)
            }
            //COMMON NAME
            if _, err := buf.Write([]byte(cert.Subject.CommonName)); err != nil {
                log.Fatal(err)
            }
        }
    } //end for

    // write data accumulated in buf out to f
    buf.WriteTo(f)

    //CLOSE THE FILE
    if err := f.Close(); err != nil {
        log.Fatal(err)
    }
}