FileStore allows you to read, write, upload, download, and interact with files, regardless of where they are stored.
It includes adapters for the following storage backends:
The package can be installed by adding file_store
to your list of dependencies in mix.exs
:
def deps do
[{:file_store, "~> 0.3"}]
end
Configure a new store:
store = FileStore.Adapters.Disk.new(
storage_path: "/path/to/store/files",
base_url: "http://example.com/files/"
)
Write a file to the store:
iex> FileStore.write(store, "foo", "hello world")
:ok
Read a file from the store:
iex> FileStore.read(store, "foo")
{:ok, "hello world"}
Get information about a file in the store:
iex> FileStore.stat("foo")
{:ok, %FileStore.Stat{key: "foo", ...}}
Upload a file to the store:
iex> FileStore.upload(store, "/path/to/upload.txt", "bar")
:ok
Download a file in the store to disk:
iex> FileStore.download(store, "bar", "/path/to/download.txt")
:ok
Get a URL for the file:
iex> FileStore.get_public_url(store, "bar")
"http://example.com/files/bar"
Get a signed URL for the file:
iex> FileStore.get_signed_url(store, "bar")
{:ok, "http://..."}
List all files:
iex> Enum.to_list(FileStore.list!(store))
["bar"]
Delete a file:
iex> FileStore.delete(store, "bar")
:ok
Delete files in bulk:
iex> FileStore.delete_all(store, "profile/images/")
:ok
To enable logging, just wrap your store with the logging middleware:
iex> store
...> |> FileStore.Middleware.Logger.new(store)
...> |> FileStore.read("test.txt")
# 02:37:30.724 [debug] READ OK key="test.txt"
{:ok, "hello"}
The errors middleware will wrap error values:
iex> store
...> |> FileStore.Middleware.Errors.new()
...> |> FileStore.read("bizcorp.jpg")
{:error, %FileStore.Error{...}}
One of the following structs will be returned:
FileStore.Error
FileStore.UploadError
FileStore.DownloadError
Because the error implements the Exception
behaviour, you can raise
it.
The prefix middleware allows you to prepend a prefix to all operations.
iex> store
...> |> FileStore.Middleware.Prefix.new(prefix: "company/logos")
...> |> FileStore.read("bizcorp.jpg")
In the example above, bizcorp.jpg
was translated to companies/logos/bizcorp.jpg
.
You can also create a dedicated store in your application.
defmodule MyApp.Storage do
use FileStore.Config, otp_app: :my_app
end
You'll need to provide configuration for this module:
config :my_app, MyApp.Storage,
adapter: FileStore.Adapters.Null,
middleware: [FileStore.Middleware.Errors]
Now, you can interact with your store more conveniently:
iex> MyApp.Storage.write("foo", "hello world")
:ok
iex> MyApp.Storage.read("foo")
{:ok, "hello world"}
In order to test the S3 adapter, we run Minio locally in a Docker container. To start the Minio service, run the following script:
$ bin/start
To run the test suite, run:
$ bin/test