我正在尝试在内存中编写图像并通过http.ResponseWriter将其发送出去,而不会触及文件系统。
我使用以下内容创建一个新文件:
file := os.NewFile(0, "temp_destination.png")
但是,我似乎无法对此文件做任何事情。这是我正在使用的函数(在http.HandleFunc中调用,它只是将文件的字节发送到浏览器),用于在临时文件上绘制蓝色矩形并将其编码为PNG:< / p>
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。谁能指出我正确的方向?关于如何正确执行内存中文件操作的替代建议是值得欢迎的。
答案 0 :(得分:5)
os.NewFile
是一个低级功能,大多数人永远不会直接使用。它需要一个已经存在的文件描述符(文件的系统表示)并将其转换为*os.File
(Go的表示)。
如果您不希望图片触及您的文件系统,请完全不要使用os包。只需将ResponseWriter视为io.Writer并将其传递给png.Encode
。
png.Encode(yourResponseWriter, img)
如果你坚持写一个&#34;在内存文件&#34;,我建议使用bytes.Buffer:
buf := new(bytes.Buffer)
png.Encode(buf, img)
return buf.Bytes()
答案 1 :(得分:2)
请详细阅读NewFile文档。 NewFile 不创建一个新文件,完全没有!它设置了一个Go os.File,它使用给定的文件描述符包装现有文件(在你的情况下为0,我认为是stdin)。
提供没有文件的图像要容易得多:只需将图像编码到ResponseWriter即可。这就是接口的用途。无需在内存文件中写入ome magic,无需使用ReadAll读取它,简单明了:写下您的回复。