我如何在Rust中告诉std :: io :: copy停止阅读并完成写作?

问题描述 投票:1回答:1

我正在通过Rust直接下载MP3音频流。由于此流是不确定的,因此我希望能够尽早取消它以保存到目前为止已下载的内容。目前,我是通过按CTRL + C来停止程序的。这将产生一个stream.mp3文件,然后我可以播放和收听,虽然可以,但是并不理想。

给出以下代码,我怎么能以编程方式尽早停止io::copy()并使其保存文件而不杀死整个程序?

extern crate reqwest;

use std::io;
use std::fs::File;

// Note that this is a direct link to the stream, not a webpage with HTML and a stream
const STREAM_URL: &str = "http://path.to/stream";

fn main() {
    let mut response = reqwest::get(STREAM_URL)
        .expect("Failed to request mp3 stream");
    let mut output = File::create("stream.mp3")
        .expect("Failed to create file!");
    io::copy(&mut response, &mut output)
        .expect("Failed to copy mp3 stream to file");
}
http io rust stream reqwest
1个回答
1
投票

正如评论所述,io::copy是一种便捷功能,用于完全读取Reader并将其内容写入Writer,而无需在中间停顿;它用于当您[[not关心中间状态,但只希望将整个内容从读取器传送到写入器时使用。

如果只想从response中获得前几Kb,则可以使用io::Read::take,它将Reader限制为您指定的任何限制。它将返回一个新的Reader,您可以将其传递给io::copy

是的,您可以在任意位置剪切MP3文件。这是一种帧格式,虽然您很可能会破坏最后一帧,但实际上,所有mp3解码器都可以处理此帧。


某事

// `Read` needs to be in scope, so .take() is available on a `io::Read` use std::io::Read; use std::io; use std::fs::File; fn main() { let mut response = reqwest::get(STREAM_URL) .expect("Failed to request mp3 stream") .take(100*1024); // Since `Response` is `Read`, we can `take` from it. let mut output = File::create("stream.mp3") .expect("Failed to create file!"); // `response` is a limited reader, so it will only read 100kb before // returning EOF, signaling a successful completion to `copy`. io::copy(&mut response, &mut output) .expect("Failed to copy mp3 stream to file"); }

© www.soinside.com 2019 - 2024. All rights reserved.