如何将文件作为可读流提供?

发布于 2025-01-25 03:21:42 字数 639 浏览 2 评论 0原文

我正在尝试创建一个提供静态文件的请求对象。 问题是:我需要做返回新响应(<可读流>)。但是,Node的fs.CreateReadStream返回readstream(node api),而不是readableStream(我相信这是Web API)。

从文件中的节点中生成readableStream的正确方法是什么?

上下文:

I'm trying to create a Request object that serves a static file.
The issue is: I need to do return new Response(<readable stream>). However, Node's fs.createReadStream returns a ReadStream (Node API) instead of a ReadableStream (which I believe is a web API).

What is the correct way to generate a ReadableStream in Node from a file?

The context:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最单纯的乌龟 2025-02-01 03:21:43

对于任何发现此问题的人 - 您可以使用createAldableStreamFromReadablereadstream转换为可读,可用于创建wendment> wendment :

import { createReadableStreamFromReadable } from '@remix-run/node';
import * as fs from 'fs';

export async function action() {
  const readableStream = fs.createReadStream('some-file.txt');
  return new Response(createReadableStreamFromReadable(readableStream));
}

For anyone finding this issue - you can use createReadableStreamFromReadable to convert ReadStream into a Readable which can be used to create a Response:

import { createReadableStreamFromReadable } from '@remix-run/node';
import * as fs from 'fs';

export async function action() {
  const readableStream = fs.createReadStream('some-file.txt');
  return new Response(createReadableStreamFromReadable(readableStream));
}

一江春梦 2025-02-01 03:21:43

我不确定我是否有所有要素可以理解返回新响应的原因(&lt;可读流&gt;),所以我假设您只需要在响应中发送文件。

混音具有我们所谓的“ 资源路由除了渲染组件(这种类型的路线都不会导出)以外,作为更通用的端点。您将能够导出可以管理不同请求方法并使用文件和标头返回新响应的加载程序。

采取此示例来自上面链接的文档想要渲染一个允许下载pdf的组件:

// app/routes/reports/$id.js

export async function loader({ params }) {
  return json(await getReport(params.id));
}

export default function Report() {
  const report = useLoaderData();
  return (
    <div>
      <h1>{report.name}</h1>
      <Link to="pdf" reloadDocument>
        View as PDF
      </Link>
      {/* ... */}
    </div>
  );
}

您会注意到&lt; link to = =“ pdf” reloAddocument&gt;其中“ pdf”与下面的路由匹配:

// app/routes/reports/$id/pdf.ts

export async function loader({ params }) {
  const report = await getReport(params.id);
  const pdf = await generateReportPDF(report);
  return new Response(pdf, {
    status: 200,
    headers: {
      "Content-Type": "app/pdf",
    },
  });
}

希望它对您有用,如果我猜正确了您需要什么!

I'm not sure I have all the elements to understand the reason for return new Response(<readable stream>) so I'm going to assume that you just need to send a file in a Response.

Remix has what we call "Resource Routes", which are used for something other than rendering a component (this type of route does not export any), as a more general-purpose endpoint. You'll be able to export a loader that can manage different request methods and returns a new Response with a file and a header.

Take this example from the doc linked above which wants to render a component allowing to download a pdf:

// app/routes/reports/$id.js

export async function loader({ params }) {
  return json(await getReport(params.id));
}

export default function Report() {
  const report = useLoaderData();
  return (
    <div>
      <h1>{report.name}</h1>
      <Link to="pdf" reloadDocument>
        View as PDF
      </Link>
      {/* ... */}
    </div>
  );
}

You will notice <Link to="pdf" reloadDocument> where "pdf" matches the route below:

// app/routes/reports/$id/pdf.ts

export async function loader({ params }) {
  const report = await getReport(params.id);
  const pdf = await generateReportPDF(report);
  return new Response(pdf, {
    status: 200,
    headers: {
      "Content-Type": "app/pdf",
    },
  });
}

Hoping that it will be useful to you if I guessed correctly what you needed!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文