簡體   English   中英

使用golang寫入文件字節進行優化

[英]Go using for write to file bytes optimize in golang

我有以下程序在.pem文件中打印出有關每個證書的信息:

package main

import (
    "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)
    }

    var blocks [][]byte
    for {
        var certDERBlock *pem.Block
        certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
        if certDERBlock == nil {
            break
        }

        if certDERBlock.Type == "CERTIFICATE" {
            blocks = append(blocks, certDERBlock.Bytes)
        }
    } //end for

    //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)
    }

    for _, block := range blocks {
        cert, err := x509.ParseCertificate(block)
        if err != nil {
            log.Println(err)
            continue
        }

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

    } //end for

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

它可以工作,但是請注意,每一行都分別寫入文件。 這似乎有點浪費,但是我對Go中的選項尚不清楚...我創建一個數組...我從證書中對其進行切片...另一個用於循環...

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

而不是使用cert。*,我應該將該數據捕獲到結構或數組中嗎?

跟進

假設最后一次寫入或任何寫入失敗,Go會回滾更改還是最后一次寫入未寫入文件? 這需要全部寫入或不寫入。

(這是我的學習方式,感謝您的幫助)

寫入內存中緩沖區的最簡單方法是使用bytes包,該包提供Buffer類型。 由於Buffer實現Writer接口 ,因此您可以更新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)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM