# #go
Вопрос:
У меня есть эхо-сервер Golang, который принимает произвольную полезную нагрузку JSON. Гарантируется, что эта полезная нагрузка всегда будет содержать файл, закодированный в строке base64, но без расширения файла, указанного в полезной нагрузке. Я хочу декодировать эту строку (готово), получить ее расширение и сохранить этот файл с этим расширением (готово). Как я могу получить расширение из декодированной строки base64? Файлы любого типа могут быть закодированы в этой строке, будь то .doc/.docx, .xls/.xlsx, .waff, .mp4, .ogg и т.д.
Используемые решения:
Вот код, который извлекает строку base64.
func (service *Inlet) getFileContentsFromPayload(payload map[string]interface{}) ([]byte, error) {
var contents []byte
for key, value := range payload {
switch value.(type) {
case string:
decoded, err := base64.StdEncoding.DecodeString(value.(string))
if err != nil {
continue
} else {
contents = decoded
delete(payload, key)
break
}
default:
continue
}
}
// just to check that encoded file is here.
if contents == nil {
service.logger.Println("No b64-encoded file given.")
return nil, echo.NewHTTPError(http.StatusBadRequest, "Please provide base64-encoded file.")
}
return contents, nil
}
Затем возвращенный фрагмент байта переходит к этой функции, которая сохраняет файл локально:
func (service *Inlet) prepareNFSData(contents []byte) (*os.File, error) {
kind, err := filetype.Match(contents)
if err != nil {
service.logger.Println(err)
return nil, echo.NewHTTPError(http.StatusBadRequest, map[string]interface{}{
"description": "Unknown extension given.",
"reason": err.Error(),
})
}
filename := fmt.Sprintf(
"%s.%s",
uuid.New().String(),
kind.Extension,
)
file, err := service.createFile(contents, filename)
if err != nil {
service.logger.Println(err)
return nil, echo.NewHTTPError(http.StatusInternalServerError, "Internal server error.")
}
return file, nil
}
Здесь использовался последний filetype
пакет решения с Match
функцией, которая должна возвращать Type
структуру, содержащую информацию о типе MIME и расширении файла. Мне нужно удалить эту строку кода.
kind, err := filetype.Match(contents)
if err != nil {
service.logger.Println(err)
return nil, echo.NewHTTPError(http.StatusBadRequest, map[string]interface{}{
"description": "Unknown extension given.",
"reason": err.Error(),
})
}
с другим решением получения расширения файла из байтового среза. Эти решения не работают для большинства образцов тестовых файлов.
Комментарии:
1. Стандартная библиотека не предоставляет лучшего решения, чем это. Если этого недостаточно, это заставляет вас искать другую стороннюю библиотеку, которая для ЭТОГО не по теме.
2. Я собираюсь связать первое, что я получил от Google: [тип файла содержимого] ( golangcode.com/get-the-content-type-of-file ) . Я знаю, что это на самом деле проверяет, какой это тип файла, вместо того, чтобы читать расширение имени файла.