亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何將可執行二進制文件的輸出寫入內存而不是磁盤

如何將可執行二進制文件的輸出寫入內存而不是磁盤

Go
慕桂英3389331 2023-02-06 14:45:15
我得到了一個像下面這樣工作的二進制文件:> ./my_bin raw.avi output_file.avioutput_file.avi是我想要的,當作業成功時,終端會打印一些詳細信息,例如:版權所有 2022 Company Inc... 成功。我想在我的代碼中運行這個命令并將其重定向output_file.avi到某個字節數組,這樣我就不必從磁盤讀取它并刪除它。我的方法類似于下面的 Golang 代碼片段:func wrongOne(stdin []byte) ([]byte, error) {    inBuf := bytes.NewBuffer(stdin)    outBuf := bytes.NewBuffer(nil)    cmd := exec.Command("./my_bin", "/dev/stdin", "/dev/stdout")    cmd.Stdin = inBuf    cmd.Stdout = outBuf    err := cmd.Run()    if err != nil {        return nil, err    }    return outBuf.Bytes(), nil // wrong}但是,返回的字節數組比下面的方法長,這會導致 MD5 檢查失敗。func correctOne(stdin []byte) ([]byte, error) {    inBuf := bytes.NewBuffer(stdin)    cmd := exec.Command("./my_bin", "/dev/stdin", "output_file")    cmd.Stdin = inBuf    err := cmd.Run()    if err != nil {        return nil, err    }    return os.ReadFile("output_file")}該wrongOne功能可以修改為以下代碼是正確的:func modifiedWrongOne(stdin []byte) ([]byte, error) {    inBuf := bytes.NewBuffer(stdin)    outBuf := bytes.NewBuffer(nil)    cmd := exec.Command("./my_bin", "/dev/stdin", "/dev/stdout")    cmd.Stdin = inBuf    cmd.Stdout = outBuf    err := cmd.Run()    if err != nil {        return nil, err    }    correct, _ := correctOne(stdin)    return outBuf.Bytes()[:len(correct)], nil // diff}我假設輸出詳細信息包含在 中,/dev/stdout因此該wrongOne函數不起作用。IE,wrongOne= 的輸出+ correctOne[]byte{"Copyright 2022 Company Inc... Success."}有沒有什么解決方案可以output_file.avi在不將其保存為文件并從磁盤讀取的情況下獲取管道?謝謝!
查看完整描述

2 回答

?
HUH函數

TA貢獻1836條經驗 獲得超4個贊

該命令將版權聲明寫入標準輸出。為避免將版權聲明與輸出文件混在一起,請使用 /dev/stdout 以外的文件作為輸出文件。

下面的函數使用Cmd.ExtraFiles管道連接到子進程中的 fd 3。該函數將數據從管道復制到字節緩沖區,并將這些字節返回給調用者。

func otherOne(stdin []byte) ([]byte, error) {

    r, w, err := os.Pipe()

    if err != nil {

        return nil, err

    }

    defer r.Close()

    defer w.Close()


    cmd := exec.Command("./my_bin", "/dev/stdin", "/dev/fd/3")

    cmd.Stdin = bytes.NewReader(stdin)

    cmd.ExtraFiles = []*os.File{w} // The first file is fd 3.

    if err := cmd.Start(); err != nil {

        return nil, err

    }

    w.Close()

    var outbuf bytes.Buffer

    if _, err := io.Copy(&outbuf, r); err != nil {

        return nil, err

    }

    if err := cmd.Wait(); err != nil {

        return nil, err

    }

    return outbuf.Bytes(), nil

}


查看完整回答
反對 回復 2023-02-06
?
侃侃無極

TA貢獻2051條經驗 獲得超10個贊

幾個月后,我想出了另一種方法來解決這個問題。基本思想與Cerise類似,即/dev/fd/3用于重定向輸出文件。之后,我們分別重定向/dev/fd/3到/dev/stdout, verbose log 到/dev/stderr by 3>&1, 1>&2。添加了一個額外gen.sh的。這是解決方案:


#gen.sh

./mybin /dev/stdin /dev/fd/3 3>&1 1>&2

// gen.go

func gen(stdin []byte) ([]byte, error) {

    inBuf := bytes.NewBuffer(stdin)

    outBuf := bytes.NewBuffer(nil)

    cmd := exec.Command("./gen.sh")

    cmd.Stdin = inBuf

    cmd.Stdout = outBuf

    cmd.Stderr = os.Stderr

    err := cmd.Run()

    if err != nil {

        return nil, err

    }

    return outBuf.Bytes(), nil

}


查看完整回答
反對 回復 2023-02-06
  • 2 回答
  • 0 關注
  • 149 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號