Files
cpp-httplib/docs-src/pages/ja/cookbook/s05-stream-response.md
T
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

65 lines
2.8 KiB
Markdown

---
title: "S05. 大きなファイルをストリーミングで返す"
order: 24
status: "draft"
---
巨大なファイルやリアルタイムに生成されるデータをレスポンスとして返したいとき、全体をメモリに載せるのは現実的ではありません。`Response::set_content_provider()`を使うと、データをチャンクごとに生成しながら送れます。
## サイズがわかっている場合
```cpp
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()`のほうがずっと簡単です。
```cpp
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として送信されます。
```cpp
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. ファイルダウンロードレスポンスを返す](../s06-download-response)を参照してください。