使用的create
use azure_storage::prelude::*;
use azure_storage_blobs:: prelude::*;
use azure_storage::CloudLocation;
use time::macros::offset;
use crate::service::config::get_blob_key;
use futures::StreamExt;
use tokio::fs::File;
use azure_core::{
tokio::fs::FileStreamBuilder,
};
use azure_core::tokio::fs::FileStream;
use tokio::io::{BufWriter, AsyncWriteExt};
使用连接字符串作为认证方式, 介绍几个常用的操作
由于我使用了tauri框架, 所以函数的返回值不能为Error, 所以不能用?,导致代码很啰嗦
1.列出账号下的所有容器
impl BlobAccount {
pub async fn new(key: & str)-> BlobAccount{
let storage_credentials = StorageCredentials::access_key(存储账号名, 连接字符串);
let client = ClientBuilder::with_location(CloudLocation::China {account: String::from(存储账号名)}, storage_credentials).blob_service_client();
BlobAccount{client}
}
pub async fn list_container(&self) -> Result<Vec<String>,String>{
let mut c = Vec::new();
let mut iv = self.client.list_containers().into_stream();
while let Some(result) = iv.next().await {
match result {
Ok(page)=> {
for container in page.containers.iter() {
c.push(container.name.clone())
}
},
Err(e)=> {
return Err(e.to_string())
}
}
}
Ok(c)
}
}
2.列出所有容器
pub async fn list_blob(&self, container_name: Vec<&str>) -> Result<Vec<BlobFile>,String> {
let mut blobs = Vec::new();
let mut x = 1;
for i in container_name {
x +=1;
let mut stream= self.client.container_client(i).list_blobs().into_stream();
while let Some(result) = stream.next().await {
match result {
Ok(page)=> {
for blob in page.blobs.blobs() {
x +=1;
let mtime = blob.properties.last_modified.to_offset(offset!(+8));
blobs.push(BlobFile{
name: blob.name.clone(),
size: convert(blob.properties.content_length).clone(),
size_int: blob.properties.content_length,
container: i.to_string(),
key: x.to_string(),
time: mtime.date().to_string() + " " + mtime.time().to_string().as_str()
})
}
},
Err(e)=> {
return Err(e.to_string())
}
}
}
}
Ok(blobs)
}
3.上传一个文件
pub async fn upload_file(&self, container_name: &str, file_path: &str, file_name: &str) -> Result<(), String>{
let file: File;
match File::open(file_path).await {
Ok(bf)=> {
file = bf
},
Err(e)=> {
return Err(e.to_string())
}
}
let mut builder = FileStreamBuilder::new(file);
let blob_client = self.client.container_client(container_name).blob_client(file_name);
if let Some(buffer_size) = BUFF_SIZE {
builder = builder.buffer_size(buffer_size);
}
if let Some(block_size) = BLOCK_SIZE {
builder = builder.block_size(block_size);
}
let mut handle : FileStream;
match builder.build().await {
Ok(h)=> {
handle = h
},
Err(e)=> {
return Err(e.to_string())
}
}
if let Some(block_size) = BLOCK_SIZE {
let mut block_list = BlockList::default();
for offset in (handle.offset..handle.stream_size).step_by(block_size as usize) {
let block_id = format!("{:08X}", offset);
match blob_client.put_block(block_id.clone(), &handle).await {
Ok(_)=> {
block_list
.blocks
.push(BlobBlockType::new_uncommitted(block_id));
match handle.next_block().await {
Ok(_)=>{}
Err(e)=> {return Err(e.to_string())}
}
},
Err(e)=> {
return Err(e.to_string())
}
}
}
match blob_client.put_block_list(block_list).await {
Ok(_) => {},
Err(e)=> { return Err(e.to_string()) }
}
} else {
// upload as one large block
match blob_client.put_block_blob(handle).await {
Ok(_)=> {},
Err(e)=> { return Err(e.to_string()) }
}
}
Ok(())
}
4.下载一个文件
pub async fn download_file(&self, container_name: &str, path: &str, blob: &str ) -> Result<(), String>{
let blob_client = self.client.container_client(container_name).blob_client(blob);
let file: File;
match File::create(path.to_string() + "\\" + blob).await {
Ok(f)=> {
file = f
}
Err(e)=> {
return Err(e.to_string())
}
}
let mut buf_write = BufWriter::new(file);
let mut stream = blob_client.get().into_stream();
while let Some(res) = stream.next().await {
match res {
Ok(data)=>{
match data.data.collect().await {
Ok(byt)=> {
match buf_write.write_all(&byt[..]).await {
Ok(_)=> {},
Err(e)=> return Err(e.to_string())
}
},
Err(e)=>{
return Err(e.to_string())
}
}
},
Err(e)=>{return Err(e.to_string())}
}
}
match buf_write.flush().await {
Ok(_)=> {},
Err(e)=> println!("{e}")
}
Ok(())
}
发表回复