将Rusoto S3 StreamingBody读成Brotli可以解压缩的东西

时间:2018-06-14 18:54:05

标签: amazon-s3 rust future brotli rusoto

rusuto_s3 StreamingBody的版本0.32(从AWS S3请求文件时返回)不再实现读取。

直到这个版本,brotli::BrotliDecompress(&mut &*would_like_to_pass_this, &mut contents);才是我从S3获取数据并进入内容的方式。 现在这会导致出现此错误消息:

  

错误[E0614]:无法取消引用类型rusoto_s3::StreamingBody

brotli::BrotliDecompress(&mut would_like_to_pass_this, &mut contents);的调整会让投诉人抱怨:

  

错误[E0277]:不满足特征限制rusoto_s3::StreamingBody::std::io::Read

     

std::io::Read

未实现特征rusoto_s3::StreamingBody

这是brotli::BrotliDecompress所必需的。

因为StreamingBody应该根据文档实现Stream,所以我尝试使用let bytes = body.concat2().wait().unwrap();收集到Vec。

然而,这失败了:

error[E0599]: no method named `concat2` found for type `rusoto_s3::StreamingBody` in the current scope                
  --> src/ingest/mod.rs:64:34
   |
64 |                 let bytes = body.concat2().wait().unwrap();                                                      
   |                                  ^^^^^^^
   |
   = help: items from traits can only be used if the trait is in scope                                                
   = note: the following trait is implemented but not in scope, perhaps add a `use` for it:                           
           candidate #1: `use futures::stream::Stream;`

正如您在完整的代码示例中所看到的,添加的建议没有任何不同的结果。

use std::io::Cursor;

use futures::stream::Stream;
use rusoto_core::Region;
use rusoto_s3::{GetObjectRequest, S3, S3Client, StreamingBody};
use serde_json;

pub fn load_data_from_s3(folder_name: String) -> CustomObject {
    let client = S3Client::simple(Region::UsWest2);

    let mut custom_object = CustomObject::empty();

    // following a list of keys (~filenames) for S3
    ["key_name1", "key_name2"].iter().for_each(|key_name| {
        let request = GetObjectRequest {
            bucket: ("bigger_bucket/".to_owned() + &folder_name).to_string(),
            key: key_name.to_string(),
            ..Default::default()
        };
        if let Ok(file) = client.get_object(&request).sync() {
            // Calculate the content size by getting the current file size
            // multiplied by a factor of 3 for the decompression
            let initial_contents_size = match file.content_length {
                Some(data) => 3 * data as usize,
                _ => 0,
            };
            let mut contents = Cursor::new(Vec::with_capacity(initial_contents_size));

            /*
             *
             * Start of the problem area
             *
             */
            // BrotliDecompress needs to act on something with the Read trait implemented,
            // which isn't the case with StreamingBody anylonger
            let would_like_to_pass_this = file.body.unwrap();
            // trying to get a Vec<u8> here
            let bytes = would_like_to_pass_this.concat2().wait().unwrap();
            brotli::BrotliDecompress(&mut &*bytes, &mut contents);
            /*
             *
             * End of the problem area
             *
             */    

            // below code is for more context
            // Reset the cursor to the beginning so we can read the decompressed data
            contents.set_position(0);

            match *key_name {
                "key_name1" => custom_object
                    .do_stuff_with_key_name1_content(serde_json::from_reader(contents).unwrap()),
                "key_name2" => custom_object
                    .do_stuff_with_key_name2_content(serde_json::from_reader(contents).unwrap()),
                _ => {}
            }
        }
    });
    custom_object
}

0 个答案:

没有答案