I'm currently using the rusoto_s3
lib to upload a file to S3. All the examples I have found do the same thing: Open a file, read the full contents of the file into memory (Vec<u8>
), then convert the Vec into a ByteStream
(which implements From<Vec<u8>>
). Here is a code example:
fn upload_file(&self, file_path: &Path) -> FileResult<PutObjectOutput> {
let mut file = File::open(file_path)?;
let mut file_data: Vec<u8> = vec![];
file.read_to_end(&mut file_data)?;
let client = S3Client::new(Region::UsEast1);
let mut request = PutObjectRequest::default();
request.body = Some(file_data.into());
Ok(client.put_object(request).sync()?)
}
This is probably acceptable for small files, but (I assume) this technique would break down as soon as you attempt to upload a file with a size greater than the available heap memory.
Another way to create a ByteStream
is by using this initializer which accepts an object implementing the Stream
trait. I would assume that File
would implement this trait, but this does not appear to be the case.
My question(s):
Is there some type which can be constructed from a File
which implements Stream
? Is the correct solution to make my own tuple struct which wraps File
and implements Stream
itself, and is this implementation trivial? Is there another solution I'm not seeing, or am I simply misunderstanding how memory is allocated in the code above?