pub struct Operator { /* private fields */ }
blocking
only.Expand description
Use OpenDAL in blocking context.
§Notes
blocking::Operator is a wrapper around AsyncOperator
. It calls async runtimes’ block_on
API to spawn blocking tasks.
Please avoid using blocking::Operator in async context.
§Examples
§Init in async context
blocking::Operator will use current async context’s runtime to handle the async calls.
This is just for initialization. You must use blocking::Operator
in blocking context.
#[tokio::main]
async fn main() -> Result<()> {
// Create fs backend builder.
let mut builder = services::S3::default().bucket("test").region("us-east-1");
let op = Operator::new(builder)?.finish();
// Build an `blocking::Operator` with blocking layer to start operating the storage.
let _: blocking::Operator = blocking::Operator::new(op)?;
Ok(())
}
§In async context with blocking functions
If blocking::Operator
is called in blocking function, please fetch a [tokio::runtime::EnterGuard
]
first. You can use [Handle::try_current
] first to get the handle and then call [Handle::enter
].
This often happens in the case that async function calls blocking function.
#[tokio::main]
async fn main() -> Result<()> {
let _ = blocking_fn()?;
Ok(())
}
fn blocking_fn() -> Result<blocking::Operator> {
// Create fs backend builder.
let mut builder = services::S3::default().bucket("test").region("us-east-1");
let op = Operator::new(builder)?.finish();
let handle = tokio::runtime::Handle::try_current().unwrap();
let _guard = handle.enter();
// Build an `blocking::Operator` to start operating the storage.
let op: blocking::Operator = blocking::Operator::new(op)?;
Ok(op)
}
§In blocking context
In a pure blocking context, we can create a runtime and use it to create the blocking::Operator
.
The following code uses a global statically created runtime as an example, please manage the runtime on demand.
static RUNTIME: LazyLock<tokio::runtime::Runtime> = LazyLock::new(|| {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap()
});
fn main() -> Result<()> {
// Create fs backend builder.
let mut builder = services::S3::default().bucket("test").region("us-east-1");
let op = Operator::new(builder)?.finish();
// Fetch the `EnterGuard` from global runtime.
let _guard = RUNTIME.enter();
// Build an `blocking::Operator` with blocking layer to start operating the storage.
let _: blocking::Operator = blocking::Operator::new(op)?;
Ok(())
}
Implementations§
Source§impl Operator
impl Operator
Sourcepub fn new(op: AsyncOperator) -> Result<Self>
pub fn new(op: AsyncOperator) -> Result<Self>
Create a new BlockingLayer
with the current runtime’s handle
Sourcepub fn info(&self) -> OperatorInfo
pub fn info(&self) -> OperatorInfo
Get information of underlying accessor.
§Examples
use opendal::blocking;
use opendal::blocking::Operator;
let info = op.info();
Source§impl Operator
§Operator blocking API.
impl Operator
§Operator blocking API.
Sourcepub fn stat(&self, path: &str) -> Result<Metadata>
pub fn stat(&self, path: &str) -> Result<Metadata>
Get given path’s metadata.
§Behavior
§Services that support create_dir
test
and test/
may vary in some services such as S3. However, on a local file system,
they’re identical. Therefore, the behavior of stat("test")
and stat("test/")
might differ
in certain edge cases. Always use stat("test/")
when you need to access a directory if possible.
Here are the behavior list:
Case | Path | Result |
---|---|---|
stat existing dir | abc/ | Metadata with dir mode |
stat existing file | abc/def_file | Metadata with file mode |
stat dir without / | abc/def_dir | Error NotFound or metadata with dir mode |
stat file with / | abc/def_file/ | Error NotFound |
stat not existing path | xyz | Error NotFound |
Refer to RFC: List Prefix for more details.
§Services that not support create_dir
For services that not support create_dir
, stat("test/")
will return NotFound
even
when test/abc
exists since the service won’t have the concept of dir. There is nothing
we can do about this.
§Examples
§Check if file exists
use opendal::blocking;
use opendal::ErrorKind;
if let Err(e) = op.stat("test") {
if e.kind() == ErrorKind::NotFound {
println!("file not exist")
}
}
Sourcepub fn stat_options(&self, path: &str, opts: StatOptions) -> Result<Metadata>
pub fn stat_options(&self, path: &str, opts: StatOptions) -> Result<Metadata>
Get given path’s metadata with extra options.
§Behavior
§Services that support create_dir
test
and test/
may vary in some services such as S3. However, on a local file system,
they’re identical. Therefore, the behavior of stat("test")
and stat("test/")
might differ
in certain edge cases. Always use stat("test/")
when you need to access a directory if possible.
Here are the behavior list:
Case | Path | Result |
---|---|---|
stat existing dir | abc/ | Metadata with dir mode |
stat existing file | abc/def_file | Metadata with file mode |
stat dir without / | abc/def_dir | Error NotFound or metadata with dir mode |
stat file with / | abc/def_file/ | Error NotFound |
stat not existing path | xyz | Error NotFound |
Refer to RFC: List Prefix for more details.
§Services that not support create_dir
For services that not support create_dir
, stat("test/")
will return NotFound
even
when test/abc
exists since the service won’t have the concept of dir. There is nothing
we can do about this.
Sourcepub fn exists(&self, path: &str) -> Result<bool>
pub fn exists(&self, path: &str) -> Result<bool>
Check if this path exists or not.
§Example
use anyhow::Result;
use opendal::blocking;
use opendal::blocking::Operator;
fn test(op: blocking::Operator) -> Result<()> {
let _ = op.exists("test")?;
Ok(())
}
Sourcepub fn create_dir(&self, path: &str) -> Result<()>
pub fn create_dir(&self, path: &str) -> Result<()>
Create a dir at given path.
§Notes
To indicate that a path is a directory, it is compulsory to include
a trailing / in the path. Failure to do so may result in
NotADirectory
error being returned by OpenDAL.
§Behavior
- Create on existing dir will succeed.
- Create dir is always recursive, works like
mkdir -p
§Examples
use opendal::blocking;
op.create_dir("path/to/dir/")?;
Sourcepub fn read(&self, path: &str) -> Result<Buffer>
pub fn read(&self, path: &str) -> Result<Buffer>
Read the whole path into a bytes.
This function will allocate a new bytes internally. For more precise memory control or
reading data lazily, please use blocking::Operator::reader
§Examples
use opendal::blocking;
let bs = op.read("path/to/file")?;
Sourcepub fn read_options(&self, path: &str, opts: ReadOptions) -> Result<Buffer>
pub fn read_options(&self, path: &str, opts: ReadOptions) -> Result<Buffer>
Read the whole path into a bytes with extra options.
This function will allocate a new bytes internally. For more precise memory control or
reading data lazily, please use blocking::Operator::reader
Sourcepub fn reader(&self, path: &str) -> Result<Reader>
pub fn reader(&self, path: &str) -> Result<Reader>
Create a new reader which can read the whole path.
§Examples
use opendal::blocking;
let r = op.reader("path/to/file")?;
Sourcepub fn reader_options(&self, path: &str, opts: ReaderOptions) -> Result<Reader>
pub fn reader_options(&self, path: &str, opts: ReaderOptions) -> Result<Reader>
Create a new reader with extra options
Sourcepub fn write_options(
&self,
path: &str,
bs: impl Into<Buffer>,
opts: WriteOptions,
) -> Result<Metadata>
pub fn write_options( &self, path: &str, bs: impl Into<Buffer>, opts: WriteOptions, ) -> Result<Metadata>
Write data with options.
§Notes
- Write will make sure all bytes has been written, or an error will be returned.
Sourcepub fn writer_options(&self, path: &str, opts: WriteOptions) -> Result<Writer>
pub fn writer_options(&self, path: &str, opts: WriteOptions) -> Result<Writer>
Create a new writer with extra options
Sourcepub fn copy(&self, from: &str, to: &str) -> Result<()>
pub fn copy(&self, from: &str, to: &str) -> Result<()>
Copy a file from from
to to
.
§Notes
from
andto
must be a file.to
will be overwritten if it exists.- If
from
andto
are the same, nothing will happen. copy
is idempotent. For samefrom
andto
input, the result will be the same.
§Examples
use opendal::blocking;
op.copy("path/to/file", "path/to/file2")?;
Sourcepub fn delete_options(&self, path: &str, opts: DeleteOptions) -> Result<()>
pub fn delete_options(&self, path: &str, opts: DeleteOptions) -> Result<()>
Sourcepub fn delete_iter<I, D>(&self, iter: I) -> Result<()>where
I: IntoIterator<Item = D>,
D: IntoDeleteInput,
pub fn delete_iter<I, D>(&self, iter: I) -> Result<()>where
I: IntoIterator<Item = D>,
D: IntoDeleteInput,
Delete an infallible iterator of paths.
Also see:
blocking::Operator::delete_try_iter
: delete an fallible iterator of paths.
Sourcepub fn delete_try_iter<I, D>(&self, try_iter: I) -> Result<()>
pub fn delete_try_iter<I, D>(&self, try_iter: I) -> Result<()>
Delete a fallible iterator of paths.
Also see:
blocking::Operator::delete_iter
: delete an infallible iterator of paths.
Sourcepub fn deleter(&self) -> Result<Deleter>
pub fn deleter(&self) -> Result<Deleter>
Create a [BlockingDeleter
] to continuously remove content from storage.
It leverages batch deletion capabilities provided by storage services for efficient removal.
Users can have more control over the deletion process by using [BlockingDeleter
] directly.
Sourcepub fn remove_all(&self, path: &str) -> Result<()>
pub fn remove_all(&self, path: &str) -> Result<()>
Sourcepub fn list(&self, path: &str) -> Result<Vec<Entry>>
pub fn list(&self, path: &str) -> Result<Vec<Entry>>
List entries that starts with given path
in parent dir.
§Notes
§Recursively List
This function only read the children of the given directory. To read
all entries recursively, use blocking::Operator::list_options("path", opts)
instead.
§Streaming List
This function will read all entries in the given directory. It could take very long time and consume a lot of memory if the directory contains a lot of entries.
In order to avoid this, you can use blocking::Operator::lister
to list entries in
a streaming way.
§Examples
use opendal::blocking;
use opendal::blocking::Operator;
use opendal::EntryMode;
let mut entries = op.list("path/to/dir/")?;
for entry in entries {
match entry.metadata().mode() {
EntryMode::FILE => {
println!("Handling file")
}
EntryMode::DIR => {
println!("Handling dir {}", entry.path())
}
EntryMode::Unknown => continue,
}
}
Sourcepub fn list_options(&self, path: &str, opts: ListOptions) -> Result<Vec<Entry>>
pub fn list_options(&self, path: &str, opts: ListOptions) -> Result<Vec<Entry>>
List entries that starts with given path
in parent dir. with options.
§Notes
§Streaming List
This function will read all entries in the given directory. It could take very long time and consume a lot of memory if the directory contains a lot of entries.
In order to avoid this, you can use blocking::Operator::lister
to list entries in
a streaming way.
Sourcepub fn lister(&self, path: &str) -> Result<Lister>
pub fn lister(&self, path: &str) -> Result<Lister>
List entries that starts with given path
in parent dir.
This function will create a new [BlockingLister
] to list entries. Users can stop listing
via dropping this Lister
.
§Notes
§Recursively List
This function only read the children of the given directory. To read
all entries recursively, use [blocking::Operator::lister_with
] and delimiter("")
instead.
§Examples
use futures::TryStreamExt;
use opendal::blocking;
use opendal::blocking::Operator;
use opendal::EntryMode;
let mut ds = op.lister("path/to/dir/")?;
for de in ds {
let de = de?;
match de.metadata().mode() {
EntryMode::FILE => {
println!("Handling file")
}
EntryMode::DIR => {
println!("Handling dir like start a new list via meta.path()")
}
EntryMode::Unknown => continue,
}
}
Sourcepub fn lister_options(&self, path: &str, opts: ListOptions) -> Result<Lister>
pub fn lister_options(&self, path: &str, opts: ListOptions) -> Result<Lister>
List entries within a given directory as an iterator with options.
This function will create a new handle to list entries.
An error will be returned if given path doesn’t end with /
.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Operator
impl !RefUnwindSafe for Operator
impl Send for Operator
impl Sync for Operator
impl Unpin for Operator
impl !UnwindSafe for Operator
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§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.