pub struct Object { /* private fields */ }
Expand description
Object is the handler for all object related operations.
Notes
Object will cache part of object metadata that pre-fetch by list or stat operations. It’s better to reuse the same object whenever possible.
Implementations§
source§impl Object
impl Object
sourcepub fn new(op: Operator, path: &str) -> Self
pub fn new(op: Operator, path: &str) -> Self
Creates a new Object with normalized path.
- All path will be converted into relative path (without any leading
/
) - Path endswith
/
means it’s a dir path. - Otherwise, it’s a file path.
sourcepub fn id(&self) -> String
pub fn id(&self) -> String
ID of object.
ID is the unique id of object in the underlying backend. In different backend, the id could have different meaning.
For example:
- In
fs
: id is the absolute path of file, like/path/to/dir/test_object
. - In
s3
: id is the full object key, likepath/to/dir/test_object
Example
use anyhow::Result;
use futures::io;
use opendal::services::memory;
use opendal::Operator;
use opendal::Scheme;
#[tokio::main]
async fn main() -> Result<()> {
let op = Operator::from_env(Scheme::Memory)?;
let id = op.object("test").id();
Ok(())
}
sourcepub fn path(&self) -> &str
pub fn path(&self) -> &str
Path of object. Path is relative to operator’s root. Only valid in current operator.
The value is the same with Metadata::path()
.
Example
use anyhow::Result;
use futures::io;
use opendal::services::memory;
use opendal::Operator;
use opendal::Scheme;
#[tokio::main]
async fn main() -> Result<()> {
let op = Operator::from_env(Scheme::Memory)?;
let path = op.object("test").path();
Ok(())
}
sourcepub fn name(&self) -> &str
pub fn name(&self) -> &str
Name of object. Name is the last segment of path.
If this object is a dir, Name
MUST endswith /
Otherwise, Name
MUST NOT endswith /
.
The value is the same with Metadata::name()
.
Example
use anyhow::Result;
use futures::io;
use opendal::services::memory;
use opendal::Operator;
use opendal::Scheme;
#[tokio::main]
async fn main() -> Result<()> {
let op = Operator::from_env(Scheme::Memory)?;
let name = op.object("test").name();
Ok(())
}
sourcepub async fn mode(&self) -> Result<ObjectMode>
pub async fn mode(&self) -> Result<ObjectMode>
Return this object entry’s object mode.
sourcepub fn blocking_mode(&self) -> Result<ObjectMode>
pub fn blocking_mode(&self) -> Result<ObjectMode>
Return this object entry’s object mode in blocking way.
sourcepub async fn create(&self) -> Result<()>
pub async fn create(&self) -> Result<()>
Create an empty object, like using the following linux commands:
touch path/to/file
mkdir path/to/dir/
Behavior
- Create on existing dir will succeed.
- Create on existing file will overwrite and truncate it.
Examples
Create an empty file
let o = op.object("path/to/file");
let _ = o.create().await?;
Create a dir
let o = op.object("path/to/dir/");
let _ = o.create().await?;
sourcepub fn blocking_create(&self) -> Result<()>
pub fn blocking_create(&self) -> Result<()>
Create an empty object, like using the following linux commands:
touch path/to/file
mkdir path/to/dir/
Behavior
- Create on existing dir will succeed.
- Create on existing file will overwrite and truncate it.
Examples
Create an empty file
let o = op.object("path/to/file");
let _ = o.blocking_create()?;
Create a dir
let o = op.object("path/to/dir/");
let _ = o.blocking_create()?;
sourcepub async fn read(&self) -> Result<Vec<u8>>
pub async fn read(&self) -> Result<Vec<u8>>
Read the whole object into a bytes.
This function will allocate a new bytes internally. For more precise memory control or
reading data lazily, please use Object::reader
Examples
let o = op.object("path/to/file");
let bs = o.read().await?;
sourcepub fn blocking_read(&self) -> Result<Vec<u8>>
pub fn blocking_read(&self) -> Result<Vec<u8>>
Read the whole object into a bytes.
This function will allocate a new bytes internally. For more precise memory control or
reading data lazily, please use Object::blocking_reader
Examples
let o = op.object("path/to/file");
let bs = o.blocking_read()?;
sourcepub async fn range_read(&self, range: impl RangeBounds<u64>) -> Result<Vec<u8>>
pub async fn range_read(&self, range: impl RangeBounds<u64>) -> Result<Vec<u8>>
Read the specified range of object into a bytes.
This function will allocate a new bytes internally. For more precise memory control or
reading data lazily, please use Object::range_reader
Notes
- The returning contnet’s length may be smaller than the range specifed.
Examples
let o = op.object("path/to/file");
let bs = o.range_read(1024..2048).await?;
sourcepub fn blocking_range_read(
&self,
range: impl RangeBounds<u64>
) -> Result<Vec<u8>>
pub fn blocking_range_read(
&self,
range: impl RangeBounds<u64>
) -> Result<Vec<u8>>
Read the specified range of object into a bytes.
This function will allocate a new bytes internally. For more precise memory control or
reading data lazily, please use Object::blocking_range_reader
Examples
let o = op.object("path/to/file");
let bs = o.blocking_range_read(1024..2048)?;
sourcepub async fn reader(&self) -> Result<ObjectReader>
pub async fn reader(&self) -> Result<ObjectReader>
Create a new reader which can read the whole object.
Examples
let o = op.object("path/to/file");
let r = o.reader().await?;
sourcepub fn blocking_reader(&self) -> Result<BlockingObjectReader>
pub fn blocking_reader(&self) -> Result<BlockingObjectReader>
Create a new reader which can read the whole object.
Examples
let o = op.object("path/to/file");
let r = o.blocking_reader()?;
sourcepub async fn range_reader(
&self,
range: impl RangeBounds<u64>
) -> Result<ObjectReader>
pub async fn range_reader(
&self,
range: impl RangeBounds<u64>
) -> Result<ObjectReader>
sourcepub fn blocking_range_reader(
&self,
range: impl RangeBounds<u64>
) -> Result<BlockingObjectReader>
pub fn blocking_range_reader(
&self,
range: impl RangeBounds<u64>
) -> Result<BlockingObjectReader>
Create a new reader which can read the specified range.
Examples
let o = op.object("path/to/file");
let r = o.blocking_range_reader(1024..2048)?;
sourcepub async fn decompress_read(&self) -> Result<Option<Vec<u8>>>
pub async fn decompress_read(&self) -> Result<Option<Vec<u8>>>
Read the whole object into a bytes with auto detected compress algorithm.
If we can’t find the correct algorithm, we return Ok(None)
instead.
Feature
This function needs to enable feature compress
.
Examples
let o = op.object("path/to/file.gz");
let bs = o.decompress_read().await?.expect("must read succeed");
sourcepub async fn decompress_reader(&self) -> Result<Option<impl Read>>
pub async fn decompress_reader(&self) -> Result<Option<impl Read>>
sourcepub async fn decompress_read_with(
&self,
algo: CompressAlgorithm
) -> Result<Vec<u8>>
pub async fn decompress_read_with(
&self,
algo: CompressAlgorithm
) -> Result<Vec<u8>>
sourcepub async fn decompress_reader_with(
&self,
algo: CompressAlgorithm
) -> Result<impl Read>
pub async fn decompress_reader_with(
&self,
algo: CompressAlgorithm
) -> Result<impl Read>
sourcepub async fn write_with(
&self,
args: OpWrite,
bs: impl Into<Vec<u8>>
) -> Result<()>
pub async fn write_with(
&self,
args: OpWrite,
bs: impl Into<Vec<u8>>
) -> Result<()>
Write data with option described in OpenDAL rfc-0661
Notes
- Write will make sure all bytes has been written, or an error will be returned.
Examples
use bytes::Bytes;
let op = Operator::from_env(Scheme::S3)?;
let o = op.object("path/to/file");
let bs = b"hello, world!".to_vec();
let args = OpWrite::new(bs.len() as u64).with_content_type("text/plain");
let _ = o.write_with(args, bs).await?;
sourcepub fn blocking_write_with(
&self,
args: OpWrite,
bs: impl Into<Vec<u8>>
) -> Result<()>
pub fn blocking_write_with(
&self,
args: OpWrite,
bs: impl Into<Vec<u8>>
) -> Result<()>
Write data with option described in OpenDAL rfc-0661
Notes
- Write will make sure all bytes has been written, or an error will be returned.
Examples
use bytes::Bytes;
let o = op.object("hello.txt");
let bs = b"hello, world!".to_vec();
let ow = OpWrite::new(bs.len() as u64).with_content_type("text/plain");
let _ = o.blocking_write_with(ow, bs)?;
sourcepub async fn write_from(&self, size: u64, br: impl Read + 'static) -> Result<()>
pub async fn write_from(&self, size: u64, br: impl Read + 'static) -> Result<()>
Write data into object from a input::Read
.
Notes
- Write will make sure all bytes has been written, or an error will be returned.
Examples
use bytes::Bytes;
use futures::io::Cursor;
let o = op.object("path/to/file");
let r = Cursor::new(vec![0; 4096]);
let _ = o.write_from(4096, r).await?;
sourcepub fn blocking_write_from(
&self,
size: u64,
br: impl BlockingRead + 'static
) -> Result<()>
pub fn blocking_write_from(
&self,
size: u64,
br: impl BlockingRead + 'static
) -> Result<()>
Write data into object from a input::BlockingRead
.
Notes
- Write will make sure all bytes has been written, or an error will be returned.
Examples
use std::io::Cursor;
use bytes::Bytes;
let o = op.object("path/to/file");
let r = Cursor::new(vec![0; 4096]);
let _ = o.blocking_write_from(4096, r)?;
sourcepub fn blocking_delete(&self) -> Result<()>
pub fn blocking_delete(&self) -> Result<()>
sourcepub async fn list(&self) -> Result<ObjectLister>
pub async fn list(&self) -> Result<ObjectLister>
List current dir object.
This function will create a new handle to list objects.
An error will be returned if object path doesn’t end with /
.
Examples
let op = Operator::from_env(Scheme::Memory)?;
let o = op.object("path/to/dir/");
let mut ds = o.list().await?;
// ObjectStreamer implements `futures::Stream`
while let Some(de) = ds.try_next().await? {
match de.mode().await? {
ObjectMode::FILE => {
println!("Handling file")
}
ObjectMode::DIR => {
println!("Handling dir like start a new list via meta.path()")
}
ObjectMode::Unknown => continue,
}
}
sourcepub fn blocking_list(&self) -> Result<BlockingObjectLister>
pub fn blocking_list(&self) -> Result<BlockingObjectLister>
List current dir object.
This function will create a new handle to list objects.
An error will be returned if object path doesn’t end with /
.
Examples
use anyhow::anyhow;
let op = Operator::from_env(Scheme::Memory)?;
let o = op.object("path/to/dir/");
let mut ds = o.blocking_list()?;
while let Some(de) = ds.next() {
let de = de?;
match de.blocking_mode()? {
ObjectMode::FILE => {
println!("Handling file")
}
ObjectMode::DIR => {
println!("Handling dir like start a new list via meta.path()")
}
ObjectMode::Unknown => continue,
}
}
sourcepub async fn stat(&self) -> Result<ObjectMetadata>
pub async fn stat(&self) -> Result<ObjectMetadata>
Get current object’s metadata without cache.
Notes
This function works exactly the same with Object::metadata
.The
only difference is it will not try to load data from cached metadata.
Use this function to detect the outside changes of object.
sourcepub async fn metadata(&self) -> Result<ObjectMetadata>
pub async fn metadata(&self) -> Result<ObjectMetadata>
Get current object’s metadata with cache.
Notes
This function will try access the local metadata cache first.
If there are outside changes of the object, metadata
could return
out-of-date metadata. To overcome this, please use Object::stat
.
Examples
use opendal::ErrorKind;
if let Err(e) = op.object("test").metadata().await {
if e.kind() == ErrorKind::ObjectNotFound {
println!("object not exist")
}
}
sourcepub async fn content_length(&self) -> Result<u64>
pub async fn content_length(&self) -> Result<u64>
The size of ObjectEntry
’s corresponding object
content_length
is a prefetched metadata field in ObjectEntry
.
sourcepub async fn content_md5(&self) -> Result<Option<String>>
pub async fn content_md5(&self) -> Result<Option<String>>
The MD5 message digest of ObjectEntry
’s corresponding object
content_md5
is a prefetched metadata field in ObjectEntry
It doesn’t mean this metadata field of object doesn’t exist if content_md5
is None
.
Then you have to call ObjectEntry::metadata()
to get the metadata you want.
sourcepub async fn last_modified(&self) -> Result<Option<OffsetDateTime>>
pub async fn last_modified(&self) -> Result<Option<OffsetDateTime>>
The last modified UTC datetime of ObjectEntry
’s corresponding object
last_modified
is a prefetched metadata field in ObjectEntry
It doesn’t mean this metadata field of object doesn’t exist if last_modified
is None
.
Then you have to call ObjectEntry::metadata()
to get the metadata you want.
sourcepub async fn etag(&self) -> Result<Option<String>>
pub async fn etag(&self) -> Result<Option<String>>
The ETag string of ObjectEntry
’s corresponding object
etag
is a prefetched metadata field in ObjectEntry
.
It doesn’t mean this metadata field of object doesn’t exist if etag
is None
.
Then you have to call ObjectEntry::metadata()
to get the metadata you want.
sourcepub fn blocking_metadata(&self) -> Result<ObjectMetadata>
pub fn blocking_metadata(&self) -> Result<ObjectMetadata>
Get current object’s metadata.
Examples
use opendal::ErrorKind;
if let Err(e) = op.object("test").blocking_metadata() {
if e.kind() == ErrorKind::ObjectNotFound {
println!("object not exist")
}
}
sourcepub async fn is_exist(&self) -> Result<bool>
pub async fn is_exist(&self) -> Result<bool>
Check if this object exists or not.
Example
use anyhow::Result;
use futures::io;
use opendal::services::memory;
use opendal::Operator;
use opendal::Scheme;
#[tokio::main]
async fn main() -> Result<()> {
let op = Operator::from_env(Scheme::Memory)?;
let _ = op.object("test").is_exist().await?;
Ok(())
}
sourcepub fn blocking_is_exist(&self) -> Result<bool>
pub fn blocking_is_exist(&self) -> Result<bool>
Check if this object exists or not.
Example
use anyhow::Result;
use opendal::services::memory;
use opendal::Operator;
use opendal::Scheme;
fn main() -> Result<()> {
let op = Operator::from_env(Scheme::Memory)?;
let _ = op.object("test").blocking_is_exist()?;
Ok(())
}
sourcepub fn presign_stat(&self, expire: Duration) -> Result<PresignedRequest>
pub fn presign_stat(&self, expire: Duration) -> Result<PresignedRequest>
Presign an operation for stat(head).
Example
use anyhow::Result;
use futures::io;
use opendal::services::memory;
use opendal::Operator;
use time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
let signed_req = op.object("test").presign_stat(Duration::hours(1))?;
let req = http::Request::builder()
.method(signed_req.method())
.uri(signed_req.uri())
.body(())?;
sourcepub fn presign_read(&self, expire: Duration) -> Result<PresignedRequest>
pub fn presign_read(&self, expire: Duration) -> Result<PresignedRequest>
Presign an operation for read.
Example
use anyhow::Result;
use futures::io;
use opendal::services::memory;
use opendal::Operator;
use time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
let signed_req = op.object("test").presign_read(Duration::hours(1))?;
let req = http::Request::builder()
.method(signed_req.method())
.uri(signed_req.uri())
.body(())?;
sourcepub fn presign_write(&self, expire: Duration) -> Result<PresignedRequest>
pub fn presign_write(&self, expire: Duration) -> Result<PresignedRequest>
Presign an operation for write.
Example
use anyhow::Result;
use futures::io;
use opendal::services::memory;
use opendal::Operator;
use time::Duration;
use opendal::Scheme;
#[tokio::main]
async fn main() -> Result<()> {
let signed_req = op.object("test").presign_write(Duration::hours(1))?;
let req = http::Request::builder()
.method(signed_req.method())
.uri(signed_req.uri())
.body(())?;
sourcepub fn to_multipart(&self, upload_id: &str) -> ObjectMultipart
pub fn to_multipart(&self, upload_id: &str) -> ObjectMultipart
Construct a multipart with existing upload id.
sourcepub async fn create_multipart(&self) -> Result<ObjectMultipart>
pub async fn create_multipart(&self) -> Result<ObjectMultipart>
Create a new multipart for current path.