1

ファイルシステムに触れることなく、メモリ内で画像を作成し、http.ResponseWriter 経由で送信しようとしています。

以下を使用して新しいファイルを作成します。

file := os.NewFile(0, "temp_destination.png")

ただし、このファイルでは何もできないようです。これは私が使用している関数です(ファイルのバイトをブラウザに送信するだけの http.HandleFunc 内で呼び出されます)。これは、一時ファイルに青い四角形を描画し、PNG としてエンコードすることを目的としています。

func ComposeImage() ([]byte) {
    img := image.NewRGBA(image.Rect(0, 0, 640, 480))
    blue := color.RGBA{0, 0, 255, 255}
    draw.Draw(img, img.Bounds(), &image.Uniform{blue}, image.ZP, draw.Src)

    // in memory destination file, instead of going to the file sys
    file := os.NewFile(0, "temp_destination.png")

    // write the image to the destination io.Writer
    png.Encode(file, img)

    bytes, err := ioutil.ReadAll(file)
    if err != nil {
        log.Fatal("Couldn't read temporary file as bytes.")
    }

    return bytes
}

呼び出しを削除してpng.Encode、ファイル バイトを返すだけでは、サーバーはハングアップし、永遠に何もしません。

呼び出しをそのままpng.Encodeにしておくと、ファイルバイト (エンコードされ、表示されると予想される PNG チャンクの一部が含まれます) が stderr/stdout (どちらかわかりません) に吐き出され、サーバーが無期限にハングします。

os.NewFile を正しく使用していないと思います。誰かが私を正しい方向に向けることができますか? メモリ内ファイル操作を適切に実行する方法に関する代替提案を歓迎します。

4

2 に答える 2

6

os.NewFileは、ほとんどの人が直接使用することのない低レベルの関数です。既存のファイル記述子 (ファイルのシステム表現) を取り、それを*os.File(Go の表現) に変換します。

画像がファイルシステムに影響を与えたくない場合は、os パッケージから完全に離れてください。ResponseWriter を io.Writer として扱い、に渡すだけpng.Encodeです。

png.Encode(yourResponseWriter, img)

「メモリ内ファイル」への書き込みを主張する場合は、bytes.Buffer を使用することをお勧めします。

buf := new(bytes.Buffer)
png.Encode(buf, img)
return buf.Bytes()
于 2013-07-12T00:23:37.443 に答える