英文:
Save an image from url to blob
问题
我可以将一个来自URL的图像下载到文件中,如这里所示:
package main
import (
"fmt"
"net/http"
"net/url"
"os"
"strings"
)
var (
fileName string
fullUrlFile string
)
func main() {
fullUrlFile = "https://i.imgur.com/m1UIjW1.jpg"
r, e := http.Get(fullUrlFile)
if e != nil {
panic(e)
}
defer r.Body.Close()
buildFileName()
// 创建目标文件
f, e := os.Create(fileName) // "m1UIjW1.jpg";
if e != nil {
panic(e)
}
defer f.Close()
// 将内容填充到目标文件中
n, e := f.ReadFrom(r.Body)
if e != nil {
panic(e)
}
fmt.Println("文件大小:", n)
}
func buildFileName() {
fileUrl, e := url.Parse(fullUrlFile)
if e != nil {
panic(e)
}
path := fileUrl.Path
segments := strings.Split(path, "/")
fileName = segments[len(segments)-1]
println(fileName)
}
但是在我的应用程序中,我希望直接将图像保存为blob到indexedDB中,在JavaScript中可以这样做:
// 获取blob
// 创建XHR
var xhr = new XMLHttpRequest(),
blob;
xhr.open("GET", "elephant.png", true);
// 将responseType设置为blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("图像已检索");
// 作为响应的文件
blob = xhr.response;
// 将接收到的blob放入IndexedDB
transaction.objectStore("elephants").put(blob, "image");
}
}, false);
// 发送XHR
xhr.send();
我理解blob
只是一个[]byte
,所以我尝试将图像下载代码中从r.Body
读取的内容转换为[]byte
,如下所示:
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
blob := bytes.NewReader(buf.Bytes())
dest, e := os.Create("test.jpg")
n2, e := dest.ReadFrom(blob)
fmt.Printf("字节数为:%d\n", n2)
但是它没有起作用!
问题是:我如何将从io.Reader
读取的[]bytes
转换为另一个可以保存在另一个目标中的io.Reader
。
英文:
I can download an image from url to file as shown here:
package main
import (
"fmt"
"net/http"
"net/url"
"os"
"strings"
)
var (
fileName string
fullUrlFile string
)
func main() {
fullUrlFile = "https://i.imgur.com/m1UIjW1.jpg"
r, e := http.Get(fullUrlFile)
if e != nil {
panic(e)
}
defer r.Body.Close()
buildFileName()
// Create distination
f, e := os.Create(fileName) // "m1UIjW1.jpg"
if e != nil {
panic(e)
}
defer f.Close()
// Fill distination with content
n, e := f.ReadFrom(r.Body)
if e != nil {
panic(e)
}
fmt.Println("File size: ", n)
}
func buildFileName() {
fileUrl, e := url.Parse(fullUrlFile)
if e != nil {
panic(e)
}
path := fileUrl.Path
segments := strings.Split(path, "/")
fileName = segments[len(segments)-1]
println(fileName)
}
But i my application, I want to save the image as blob directly from uel to indexedDB, in JavaScript this can be done as:
// Get the blob
// Create XHR
var xhr = new XMLHttpRequest(),
blob;
xhr.open("GET", "elephant.png", true);
// Set the responseType to blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("Image retrieved");
// File as response
blob = xhr.response;
// Put the received blob into IndexedDB
transaction.objectStore("elephants").put(blob, "image");
}
}, false);
// Send XHR
xhr.send();
My understanding the the blob
is nothing but a []byte
, so I tried converting the r.Body
read in the image downloading code to []byte
as:
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
blob := bytes.NewReader(buf.Bytes())
dest, e := os.Create("test.jpg")
n2, e := dest.ReadFrom(blob)
fmt.Printf("The number of bytes are: %d\n", n2)
But it did not work!
The question is: How can I convert []bytes
read from an io.Reader
to another io.Reader
that I can save in another destination.
答案1
得分: 1
我找到了,它非常简单,可以使用以下两种方法之一:
方法一:
var dest []byte
blob := bytes.NewBuffer(dest)
io.Copy(blob, r.Body)
方法二:
var dest []byte
blob := bytes.NewBuffer(dest)
b, e := ioutil.ReadAll(r.Body)
if e != nil {
panic(e)
}
src := bytes.NewReader(b)
io.Copy(blob, src)
在这两种情况下,一旦r.Body
或者基于它创建的任何io.Writer
被使用一次后,就会完全消耗掉。
现在我的代码变成了:
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
)
var (
fileName string
fullUrlFile string
)
func main() {
fullUrlFile = "https://i.imgur.com/m1UIjW1.jpg"
r, e := http.Get(fullUrlFile)
if e != nil {
panic(e)
}
defer r.Body.Close()
buildFileName()
// 创建 blob
var dest []byte
blob := bytes.NewBuffer(dest)
io.Copy(blob, r.Body)
add_to_database(blob)
}
func buildFileName() {
fileUrl, e := url.Parse(fullUrlFile)
if e != nil {
panic(e)
}
path := fileUrl.Path
segments := strings.Split(path, "/")
fileName = segments[len(segments)-1]
println(fileName)
}
func add_to_database(blob *bytes.Buffer){}
请注意,我只翻译了代码部分,其他内容不包括在内。
英文:
I found it, it was very simple, either using:
var dest []byte
blob := bytes.NewBuffer(dest)
io.Copy(blob, r.Body)
or using:
var dest []byte
blob := bytes.NewBuffer(dest)
b, e := ioutil.ReadAll(r.Body)
if e != nil {
panic(e)
}
src := bytes.NewReader(b)
io.Copy(blob, src)
In both cases, once r.Body
or any io.Writer
created based on it, is valid for one time usage, after that it is consumed in full.
my code now became:
package main
import (
"bytes"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
)
var (
fileName string
fullUrlFile string
)
func main() {
fullUrlFile = "https://i.imgur.com/m1UIjW1.jpg"
r, e := http.Get(fullUrlFile)
if e != nil {
panic(e)
}
defer r.Body.Close()
buildFileName()
// Create blob
var dest []byte
blob := bytes.NewBuffer(dest)
io.Copy(blob, r.Body)
add_to_database(blob)
}
func buildFileName() {
fileUrl, e := url.Parse(fullUrlFile)
if e != nil {
panic(e)
}
path := fileUrl.Path
segments := strings.Split(path, "/")
fileName = segments[len(segments)-1]
println(fileName)
}
func add_to_database(blob *bytes.Buffer){}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论