使用的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(()) }
发表回复