Golang:Как получить расширение файла из байтового фрагмента?

# #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 ) . Я знаю, что это на самом деле проверяет, какой это тип файла, вместо того, чтобы читать расширение имени файла.