Files
cpp-httplib/docs-src/pages/ja/cookbook/s05-stream-response.md
yhirose c95d799180 Polish the wording of the updated docs pages
Reword the Japanese sentences so they read naturally, and correct the
size of the llama.cpp server sources in the code reading chapter.
2026-10-08 20:39:13 -04:00

2.8 KiB

title, order, status
title order status
S05. 大きなファイルをストリーミングで返す 24 draft

巨大なファイルやリアルタイムに生成されるデータをレスポンスとして返したいとき、全体をメモリに載せるのは現実的ではありません。Response::set_content_provider()を使うと、データをチャンクごとに生成しながら送れます。

サイズがわかっている場合

svr.Get("/download", [](const httplib::Request &req, httplib::Response &res) {
  size_t total_size = get_file_size("large.bin");

  res.set_content_provider(
    total_size, "application/octet-stream",
    [](size_t offset, size_t length, httplib::DataSink &sink) {
      auto n = std::min(length, size_t(64 * 1024));
      auto data = read_range_from_file("large.bin", offset, n);
      sink.write(data.data(), data.size());
      return true;
    });
});

ラムダは繰り返し呼ばれ、そのたびにoffset(ここまでに送った位置)とlength(残りのバイト数)が渡されます。lengthは残り全部を指すので、上の例のように1回に読む量を自分で区切ってsink.write()で送ります。こうすれば、メモリに載るのは常に小さなチャンクだけです。

ファイルをそのまま返す

ただファイルを返すだけなら、set_file_content()のほうがずっと簡単です。

svr.Get("/download", [](const httplib::Request &req, httplib::Response &res) {
  res.set_file_content("large.bin", "application/octet-stream");
});

内部でストリーミング送信をしてくれるので、大きなファイルでも安心です。Content-Typeを省略すれば、拡張子から自動で判定されます。

サイズが不明な場合はチャンク転送

リアルタイムに生成されるデータなど、サイズが事前にわからないときはset_chunked_content_provider()を使います。HTTP chunked transfer-encodingとして送信されます。

svr.Get("/events", [](const httplib::Request &req, httplib::Response &res) {
  res.set_chunked_content_provider(
    "text/plain",
    [](size_t offset, httplib::DataSink &sink) {
      auto chunk = produce_next_chunk();
      if (chunk.empty()) {
        sink.done(); // 送信終了
        return true;
      }
      sink.write(chunk.data(), chunk.size());
      return true;
    });
});

データがもう無くなったらsink.done()を呼んで終了します。

Note: プロバイダラムダは複数回呼ばれます。キャプチャする変数のライフタイムに気をつけてください。必要ならstd::shared_ptrなどで包みましょう。

ファイルダウンロードとして扱いたい場合はS06. ファイルダウンロードレスポンスを返すを参照してください。