【问题标题】:How to efficiently serve a file with actix-web如何使用 actix-web 有效地提供文件
【发布时间】:2022-01-06 22:12:30
【问题描述】:

actix-web 中,可以通过在处理程序中返回来提供文件:

HttpResponse::Ok().streaming(file)

但在这里,file 必须实现 Stream<Item = Result<Bytes, E>> 特征。 crate async_std 中的 File 类型没有实现它,所以我创建了一个实现它的包装器:

struct FileStreamer {
    file: File,
}

impl Stream for FileStreamer {
    type Item = Result<Bytes, std::io::Error>;

    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        let mut buf = [0; 1024];
        self.file.read(&mut buf).poll_unpin(cx).map(|r| {
            r.map(|n| {
                if n == 0 {
                    None
                } else {
                    Some(Bytes::copy_from_slice(&buf[0..n]))
                }
            })
            .transpose()
        })
    }
}

它可以工作,但有一个问题。对于每次调用 read,我们都会创建一个 Bytes 的新实例,这是一个动态分配的缓冲区。

这是在 actix-web 中提供文件的最有效方式吗?

我也觉得,在这种情况下选择合适的缓冲区大小实际上更为关键,因为一个小的缓冲区会导致重复的系统调用,而一个太大的缓冲区会导致内存分配缓慢,甚至不会被完全使用。

我是否可以将重复动态分配视为性能问题?

PS:该文件不是静态的,它会被修改和删除,因此,控制读取过程是必要的。

【问题讨论】:

  • 文件是否在文件系统上?
  • 肯定的。在本地存储上。
  • 您可以根据需要使用文件系统。无需将事情过度复杂化。

标签: performance rust allocation actix-web rust-actix


【解决方案1】:

来自actix-webdocumentation

actix-web 将根据路径发送有问题的文件。此示例从 URL 获取动态路径。我觉得你在流式传输文件的问题上想多了。

use actix_files::NamedFile;
use actix_web::{HttpRequest, Result};
use std::path::PathBuf;

async fn index(req: HttpRequest) -> Result<NamedFile> {
    let path: PathBuf = req.match_info().query("filename").parse().unwrap();
    Ok(NamedFile::open(path)?)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    use actix_web::{web, App, HttpServer};

    HttpServer::new(|| App::new().route("/{filename:.*}", web::get().to(index)))
        .bind("127.0.0.1:8080")?
        .run()
        .await
}

【讨论】:

  • 嗯,你可能是对的,我可能想多了这个问题。但是我想控制文件的读取过程,因为它不是静态文件,可以被另一个handler删除(我打算用mutex或者其他同步工具,防止并发动作)
  • 我认为你不需要任何弧或互斥体。您可以检查文件是否在文件系统上并相应地更新/删除它。
猜你喜欢
  • 1970-01-01
  • 2015-06-05
  • 2016-05-04
  • 1970-01-01
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
相关资源
最近更新 更多