Struct Writer

Source
pub struct Writer { /* private fields */ }
Expand description

Writer is designed to write data into given path in an asynchronous manner.

§Notes

Please make sure either close or abort has been called before dropping the writer otherwise the data could be lost.

§Usage

§Write Multiple Chunks

Some services support to write multiple chunks of data into given path. Services that doesn’t support write multiple chunks will return ErrorKind::Unsupported error when calling write at the second time.

use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> Result<()> {
    let mut w = op.writer("path/to/file").await?;
    w.write(vec![1; 1024]).await?;
    w.write(vec![2; 1024]).await?;
    w.close().await?;
    Ok(())
}

§Write like Sink

use anyhow::Result;
use futures::SinkExt;
use opendal::Operator;

async fn test(op: Operator) -> Result<()> {
    let mut w = op.writer("path/to/file").await?.into_bytes_sink();
    w.send(vec![1; 1024].into()).await?;
    w.send(vec![2; 1024].into()).await?;
    w.close().await?;
    Ok(())
}

§Write like AsyncWrite

use anyhow::Result;
use futures::AsyncWriteExt;
use opendal::Operator;

async fn test(op: Operator) -> Result<()> {
    let mut w = op.writer("path/to/file").await?.into_futures_async_write();
    w.write(&vec![1; 1024]).await?;
    w.write(&vec![2; 1024]).await?;
    w.close().await?;
    Ok(())
}

§Write with append enabled

Writer also supports to write with append enabled. This is useful when users want to append some data to the end of the file.

  • If file doesn’t exist, it will be created and just like calling write.
  • If file exists, data will be appended to the end of the file.

Possible Errors:

  • Some services store normal file and appendable file in different way. Trying to append on non-appendable file could return ErrorKind::ConditionNotMatch error.
  • Services that doesn’t support append will return ErrorKind::Unsupported error when creating writer with append enabled.

Implementations§

Source§

impl Writer

Source

pub async fn write(&mut self, bs: impl Into<Buffer>) -> Result<()>

Write Buffer into writer.

This operation will write all data in given buffer into writer.

§Examples
use bytes::Bytes;
use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> Result<()> {
    let mut w = op.writer("hello.txt").await?;
    // Buffer can be created from continues bytes.
    w.write("hello, world").await?;
    // Buffer can also be created from non-continues bytes.
    w.write(vec![Bytes::from("hello,"), Bytes::from("world!")])
        .await?;

    // Make sure file has been written completely.
    w.close().await?;
    Ok(())
}
Source

pub async fn write_from(&mut self, bs: impl Buf) -> Result<()>

Write bytes::Buf into inner writer.

This operation will write all data in given buffer into writer.

§TODO

Optimize this function to avoid unnecessary copy.

Source

pub async fn abort(&mut self) -> Result<()>

Abort the writer and clean up all written data.

§Notes

Abort should only be called when the writer is not closed or aborted, otherwise an unexpected error could be returned.

Source

pub async fn close(&mut self) -> Result<Metadata>

Close the writer and make sure all data have been committed.

§Notes

Close should only be called when the writer is not closed or aborted, otherwise an unexpected error could be returned.

Source

pub fn into_sink(self) -> BufferSink

Convert writer into BufferSink which implements [Sink<Buffer>].

§Notes

BufferSink is a zero-cost abstraction. The underlying writer will reuse the Bytes and won’t perform any copy operation over data.

§Examples
§Basic Usage
use std::io;

use bytes::Bytes;
use futures::SinkExt;
use opendal::Buffer;
use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> io::Result<()> {
    let mut s = op.writer("hello.txt").await?.into_sink();
    let bs = "Hello, World!".as_bytes();
    s.send(Buffer::from(bs)).await?;
    s.close().await?;

    Ok(())
}
§Concurrent Write
use std::io;

use bytes::Bytes;
use futures::SinkExt;
use opendal::Buffer;
use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> io::Result<()> {
    let mut w = op
        .writer_with("hello.txt")
        .concurrent(8)
        .chunk(256)
        .await?
        .into_sink();
    let bs = "Hello, World!".as_bytes();
    w.send(Buffer::from(bs)).await?;
    w.close().await?;

    Ok(())
}
Source

pub fn into_futures_async_write(self) -> FuturesAsyncWriter

Convert writer into FuturesAsyncWriter which implements futures::AsyncWrite,

§Notes

FuturesAsyncWriter is not a zero-cost abstraction. The underlying writer requires an owned Buffer, which involves an extra copy operation.

FuturesAsyncWriter is required to call close() to make sure all data have been written to the storage.

§Examples
§Basic Usage
use std::io;

use futures::io::AsyncWriteExt;
use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> io::Result<()> {
    let mut w = op.writer("hello.txt").await?.into_futures_async_write();
    let bs = "Hello, World!".as_bytes();
    w.write_all(bs).await?;
    w.close().await?;

    Ok(())
}
§Concurrent Write
use std::io;

use futures::io::AsyncWriteExt;
use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> io::Result<()> {
    let mut w = op
        .writer_with("hello.txt")
        .concurrent(8)
        .chunk(256)
        .await?
        .into_futures_async_write();
    let bs = "Hello, World!".as_bytes();
    w.write_all(bs).await?;
    w.close().await?;

    Ok(())
}
Source

pub fn into_bytes_sink(self) -> FuturesBytesSink

Convert writer into FuturesBytesSink which implements futures::Sink<Bytes>.

§Notes

FuturesBytesSink is a zero-cost abstraction. The underlying writer will reuse the Bytes and won’t perform any copy operation.

§Examples
§Basic Usage
use std::io;

use bytes::Bytes;
use futures::SinkExt;
use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> io::Result<()> {
    let mut w = op.writer("hello.txt").await?.into_bytes_sink();
    let bs = "Hello, World!".as_bytes();
    w.send(Bytes::from(bs)).await?;
    w.close().await?;

    Ok(())
}
§Concurrent Write
use std::io;

use bytes::Bytes;
use futures::SinkExt;
use opendal::Operator;
use opendal::Result;

async fn test(op: Operator) -> io::Result<()> {
    let mut w = op
        .writer_with("hello.txt")
        .concurrent(8)
        .chunk(256)
        .await?
        .into_bytes_sink();
    let bs = "Hello, World!".as_bytes();
    w.send(Bytes::from(bs)).await?;
    w.close().await?;

    Ok(())
}

Auto Trait Implementations§

§

impl Freeze for Writer

§

impl !RefUnwindSafe for Writer

§

impl Send for Writer

§

impl Sync for Writer

§

impl Unpin for Writer

§

impl !UnwindSafe for Writer

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ServiceExt for T

Source§

fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>
where Self: Sized,

Apply a transformation to the response body. Read more
Source§

fn decompression(self) -> Decompression<Self>
where Self: Sized,

Decompress response bodies. Read more
Source§

fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using HTTP status codes. Read more
Source§

fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>
where Self: Sized,

High level tracing that classifies responses using gRPC headers. Read more
Source§

fn follow_redirects(self) -> FollowRedirect<Self>
where Self: Sized,

Follow redirect resposes using the Standard policy. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> MaybeSend for T
where T: Send,