go - 在 Go 中获取文件的内容类型时遇到问题
问题描述
我有一个函数,我在其中接收一个 base64 字符串并获取它的内容(PDF 或 JPEG)。我读入 base64 内容,将其转换为字节并将其解码为文件。然后我创建一个文件,我将在其中输出解码后的文件(JPEG 或 PDF)。然后我将字节写入它。然后我在它上面调用我的 GetFileContentType,它返回给我一个空字符串。如果我单独运行这些函数,就像我首先创建解码文件的第一个函数一样,然后结束它。然后调用第二个函数来获取内容类型,它可以工作并将其返回为 JPEG 或 PDF。我在这里做错了什么?有没有更好的方法来做到这一点?
func ConvertToJPEGBase64(
src string,
dst string,
) error {
b, err := ioutil.ReadFile(src)
if err != nil {
return err
}
str := string(b)
byteArray, err := base64.StdEncoding.DecodeString(str)
if err != nil {
return err
}
f, err := os.Create(dst)
if err != nil {
return err
}
if _, err := f.Write(byteArray); err != nil {
return err
}
f.Sync()
filetype, err := client.GetFileContentType(f)
if err != nil {
return err
}
if strings.Contains(filetype, "jpeg") {
// do something
} else {
// do something else
}
return nil
}
// GetFileContentType tells us the type of file
func GetFileContentType(out *os.File) (string, error) {
// Only the first 512 bytes are used to sniff the content type.
buffer := make([]byte, 512)
_, err := out.Read(buffer)
if err != nil {
return "", err
}
contentType := http.DetectContentType(buffer)
return contentType, nil
}
解决方案
问题是GetFileContentType
从文件末尾读取。在调用调用之前修复此问题GetFileContentType
:
if _, err := f.Seek(io.SeekStart, 0); err != nil {
return err
}
更好的解决方法是使用已经在内存中的文件数据。这将代码简化到不需要GetFileContentType
函数的程度。
func ConvertToJPEGBase64(
src string,
dst string,
) error {
b, err := ioutil.ReadFile(src)
if err != nil {
return err
}
str := string(b)
byteArray, err := base64.StdEncoding.DecodeString(str)
if err != nil {
return err
}
f, err := os.Create(dst)
if err != nil {
return err
}
defer f.Close() // <-- Close the file on return.
if _, err := f.Write(byteArray); err != nil {
return err
}
fileType := http.DetectContentType(byteArray) // <-- use data in memory
if strings.Contains(fileType, "jpeg") {
// do something
} else {
// do something else
}
return nil
}
可以使用以下方法消除更多代码ioutil.WriteFile
:
func ConvertToJPEGBase64(src, dst string) error {
b, err := ioutil.ReadFile(src)
if err != nil {
return err
}
byteArray, err := base64.StdEncoding.DecodeString(string(b))
if err != nil {
return err
}
if err := ioutil.WriteFile(dst, byteArray, 0666); err != nil {
return err
}
fileType := http.DetectContentType(byteArray)
if strings.Contains(fileType, "jpeg") {
// do something
} else {
// do something else
}
return nil
}
推荐阅读
- python - 使用 HTML5 编写器删除 docutils 输出中的 docinfo
- c - CMake 指示编译器不支持标志,但它支持
- azure - Azure Functions 使用 System.Data.SqlClient 预编译的 c# 缺少参考
- raku - 地图、嵌套地图和接收器上下文
- javascript - 禁用印地语字符作为输入类型号的输入
- sharepoint - SharePoint online - 单击文档时拦截文档请求
- java - 如何弄清楚为什么我的 Java 应用程序在退出后继续运行?
- python - 如何枚举张量流中的张量?
- python - 用 numpy 数组实现 softmax 函数
- php - 如何在 laravel 5.6 中更改 tymon jwt 身份验证以使用成员模型而不是用户模型?