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 withappend
enabled.
Implementations§
source§impl Writer
impl Writer
sourcepub async fn write(&mut self, bs: impl Into<Buffer>) -> Result<()>
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(())
}
sourcepub async fn write_from(&mut self, bs: impl Buf) -> Result<()>
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.
sourcepub async fn abort(&mut self) -> Result<()>
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.
sourcepub async fn close(&mut self) -> Result<()>
pub async fn close(&mut self) -> Result<()>
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.
sourcepub fn into_futures_async_write(self) -> FuturesAsyncWriter
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(())
}
sourcepub fn into_bytes_sink(self) -> FuturesBytesSink
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.