Библиотека для работы с хранилищами данных на Golang: go-storage
go-storage — библиотека для хранения данных, независимая от поставщика.
«Напиши один раз, запускай везде».
package main
import (
"log"
"go.beyondstorage.io/v5/services"
"go.beyondstorage.io/v5/types"
// Добавляем поддержку файловой системы
_ "go.beyondstorage.io/services/fs/v4"
// Добавляем поддержку S3
_ "go.beyondstorage.io/services/s3/v3"
// Добавляем поддержку GCS
_ "go.beyondstorage.io/services/gcs/v3"
// Добавляем поддержку Azure Blob Storage
_ "go.beyondstorage.io/services/azblob/v3"
// Больше поддержки можно найти в BeyondStorage.
_ "go.beyondstorage.io/services/xxx"
)
func main() {
// Инициализируем Storager из строки подключения.
store, err := services.NewStoragerFromString("s3://bucket_name/path/to/workdir")
if err != nil {
log.Fatalf("service init failed: %v", err)
}
// Записываем данные из io.Reader в hello.txt
n, err := store.Write("hello.txt", r, length)
// Считываем данные из hello.txt в io.Writer
n, err := store.Read("hello.txt", w)
// Получаем метаданные объекта hello.txt с помощью Stat
o, err := store.Stat("hello.txt")
// Используем функции объекта для получения метаданных
length, ok := o.GetContentLength()
// List создаёт итератор объектов под путём.
it, err := store.List("path")
for {
// Используем iterator.Next для извлечения следующего объекта, пока не встретим IterateDone.
o, err := it.Next()
if errors.Is(err, types.IterateDone) {
break
}
}
// Удаляем hello.txt
err = store.Delete("hello.txt")
}
Дополнительные примеры можно найти на странице go-storage-example.
16 стабильных сервисов, прошедших все интеграционные тесты.
InterPlanetary File System — ipfs
[qiniu kodo] — kodo
Данные, которые хранятся только в памяти — memory
MinIO — minio
Huawei Object Storage Service — obs
Aliyun Object Storage — oss
QingStor Object Storage — qingstor
Amazon S3 — s3
3 бета-сервиса, в которых реализованы необходимые функции, но не пройдены интеграционные тесты (integration tests)
— Hadoop Distributed File System — hdfs
— Файлы tar — tar
— [UPYUN Storage Service] — uss
4 альфа-сервиса в стадии разработки
— Microsoft OneDrive — onedrive
— StorJ — storj
— WebDAV — webdav
— Файлы zip — zip
Дополнительные идеи для сервисов можно найти на странице отслеживания интеграции сервисов (Service Integration Tracking).
Основные операции:
meta := store.Metadata()
_ := meta.GetWorkDir() // Получить объект WorkDir
_, ok := meta.GetWriteSizeMaximum() // Получить максимальный размер для операции записи
// Прочитать 2048 байт со смещением 1024 в io.Writer.
n, err := store.Read("path", w, pairs.WithOffset(1024), pairs.WithSize(2048))
// Записать 2048 байт из io.Reader
n, err := store.Write("path", r, 2048)
o, err := store.Stat("path")
if errors.Is(err, services.ErrObjectNotExist) {
// объект не существует
}
length, ok := o.GetContentLength() // получить длину содержимого объекта.
err := store.Delete("path") // Удалить объект "path"
it, err := store.List("path")
for {
o, err := it.Next()
if err != nil && errors.Is(err, types.IterateDone) {
// список завершён
}
length, ok := o.GetContentLength() // получить длину содержимого объекта.
}
Расширенные операции:
err := store.(Copier).Copy(src, dst) // Скопировать объект из src в dst.
err := store.(Mover).Move(src, dst) // Переместить объект из src в dst.
url, err := store.(Reacher).Reach("path") // Сгенерировать URL для объекта.
o, err := store.(Direr).CreateDir("path") // Создать объект dir.
Манипуляции с большими файлами:
ms := store.(Multiparter)
// Создать многокомпонентный объект.
o, err := ms.CreateMultipart("path")
// Записать 1024 байта из io.Reader в многокомпонентную часть с индексом 1
n, part, err := ms.WriteMultipart(o, r, 1024, 1)
// Завершить многокомпонентный объект. **err := ms.CompleteMultipart(o, []*Part{part})**
err = ms.CompleteMultipart (o, *Part {part}).
**Append: allow appending to an object**
```go
as := store.(Appender)
// Создаём объект, к которому можно добавить данные.
o, err := as.CreateAppend("path")
// Записываем 1024 байта из io.Reader.
n, err := as.WriteAppend(o, r, 1024)
// Фиксируем изменения в добавленном объекте.
err = as.CommitAppend(o)
Добавить: разрешить добавление данных к объекту.
Block: allow combining an object with block ids
bs := store.(Blocker)
// Создаем блочный объект.
o, err := bs.CreateBlock("path")
// Пишем 1024 байта из io.Reader с идентификатором блока "id-abc".
n, err := bs.WriteBlock(o, r, 1024, "id-abc")
// Объединяем блоки по идентификаторам.
err := bs.CombineBlock(o, []string{"id-abc"})
Блок: разрешить объединение объекта с другими объектами по их идентификатору.
Page: allow doing random writes
ps := store.(Pager)
// Создаём страничный объект.
o, err := ps.CreatePage("path")
// Записываем 1024 байта из io.Reader со смещением 2048.
n, err := ps.WritePage(o, r, 1024, 2048)
Страница: разрешить произвольную запись данных.
Глобальные метаданные объекта:
id
: уникальный ключ в сервисе;name
: относительный путь к рабочей директории сервиса;mode
: режим объекта может быть комбинацией read
, dir
, part
и других;etag
: тег сущности, как определено в rfc2616;content-length
: размер содержимого объекта;content-md5
: дайджест md5, как определено в rfc2616;content-type
: тип носителя, как определено в rfc2616;last-modified
: время последнего обновления объекта.Системные метаданные объекта:
метаданные системы сервиса, такие как storage-class
и т. д.
o, err := store.Stat("path")
// Получаем системные метаданные сервиса через API, предоставляемый go-service-s3.
om := s3.GetObjectSystemMetadata(o)
_ = om.StorageClass // класс хранения этого объекта
_ = om.ServerSideEncryptionCustomerAlgorithm // алгоритм шифрования SSE этого объекта
Самоподдерживающийся кодогенератор definitions помогает генерировать все наши API, пары и метаданные.
Сгенерированные пары, которые можно использовать в качестве необязательных аргументов API.
func WithContentMd5(v string) Pair {
return Pair{
Key: "content_md5",
Value: v,
}
}
Сгенерированный объект метаданных, который можно использовать для получения content md5 из объекта.
func (o *Object) GetContentMd5() (string, bool) {
o.stat()
if o.bit&objectIndexContentMd5 != 0 {
return o.contentMd5, true
}
return "", false
}
Поддержка Server-Side Encrypt через системные пары и системные метаданные, и мы можем использовать Default Pairs, чтобы упростить задачу.
func NewS3SseC(key []byte) (types.Storager, error) {
defaultPairs := s3.DefaultStoragePairs{
Write: []types.Pair{
// Required, must be AES256
s3.WithServerSideEncryptionCustomerAlgorithm(s3.ServerSideEncryptionAes256),
// Required, your AES-256 key, a 32-byte binary value
s3.WithServerSideEncryptionCustomerKey(key),
},
// Now you have to provide customer key to read encrypted data
Read: []types.Pair{
// Required, must be AES256
s3.WithServerSideEncryptionCustomerAlgorithm(s3.ServerSideEncryptionAes256),
// Required, your AES-256 key, a 32-byte binary value
s3.WithServerSideEncryptionCustomerKey(key),
}}
return s3.NewStorager(..., s3.WithDefaultStoragePairs(defaultPairs))
}
В запросе представлен текст на английском языке, связанный с разработкой программного обеспечения. В тексте обсуждаются различные аспекты работы с объектами и метаданными в системе хранения данных, а также вопросы шифрования данных и использования парных значений.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )