背景
在进行文件传输时,常常会遇到由于各种原因中断传输的情况。若要再次传输,通常需要重新开始传输,浪费时间和带宽资源。一种有效的解决方案是实现断点续传功能,即能够在传输中断后,从断点处继续传输,从而提高传输效率。在本文中,我们将会学习如何在 Deno 中实现这一功能。
原理
断点续传功能的实现原理是通过文件的读取和写入操作来控制传输的起始位置。设我们要传输的文件为 file.txt,已经传输的字节数为 n,则继续传输时可以通过设置读取文件的起始位置为 n,从而从文件的 n 位置开始继续传输。
在 Deno 中,我们可以使用 Deno.openSync() 函数打开需要传输的文件,并使用 Deno.seek() 函数指定文件读写的起始位置。具体实现代码如下:
// www.javascriptcn.com code example
const file = Deno.openSync("file.txt");
const buf = new Uint8Array(1024);
// 指定文件读写起始位置
Deno.seek(file.rid, n, Deno.SeekMode.Start);
// 循环读取文件和传输数据
while (true) {
const r = await file.read(buf);
if (r === null) {
break;
}
const data = buf.slice(0, r as number);
await upload(data).catch(() => {
// 传输中断,记录已传输的字节数
n += data.length;
fs.writeFileSync("resume.txt", `resume from ${n}`);
Deno.exit(1);
});
// 记录已传输的字节数
n += data.length;
}
// 传输完成,删除断点记录文件
fs.unlinkSync("resume.txt");其中,Deno.seek() 函数需要指定文件的读写模式(Deno.SeekMode),常见的模式有:
Deno.SeekMode.Start:从文件起始位置开始读写。Deno.SeekMode.Current:在当前位置上偏移指定的字节数。Deno.SeekMode.End:从文件结尾处开始读写。
在传输过程中,若传输中断,我们可以记录已传输的字节数和传输起始时间到一个文件中,从而在后续传输中,从断点处开始继续传输。此外,在传输结束后,我们需要删除这个记录文件。
实践
为了演示如何在 Deno 中实现断点续传功能,我们可以编写一个简单的上传文件的程序。在这个程序中,我们需要实现将本地的文件上传到服务器,并且支持断点续传操作。
// www.javascriptcn.com code example
async function upload(file: string) {
const stat = fs.statSync(file);
let n = 0;
// 如果存在断点记录文件,则从记录的起始位置开始继续传输
if (fs.existsSync("resume.txt")) {
const resume = fs.readFileSync("resume.txt", "utf-8");
n = parseInt(resume.replace("resume from ", ""));
}
// 打开需要上传的文件
const f = Deno.openSync(file);
// 指定文件读写起始位置
Deno.seek(f.rid, n, Deno.SeekMode.Start);
while (true) {
const buf = new Uint8Array(1024);
const r = await f.read(buf);
if (r === null) {
break;
}
// 上传数据到服务器
const data = buf.slice(0, r as number);
await uploadChunk(data).catch(() => {
// 传输中断,记录已传输的字节数
n += data.length;
fs.writeFileSync("resume.txt", `resume from ${n}`);
Deno.exit(1);
});
// 记录已传输的字节数
n += data.length;
}
// 上传结束,删除断点记录文件
fs.unlinkSync("resume.txt");
}
async function uploadChunk(data: Uint8Array) {
// 向服务器发送数据的代码
}
upload("file.txt");在这个程序中,我们使用了 Deno.openSync() 函数打开需要上传的文件,并使用 Deno.seek() 函数指定读取文件的起始位置。如果存在断点记录文件,则从记录的起始位置开始继续传输。
在传输数据时,我们使用了 await uploadChunk(data) 的方式向服务器发送数据,其中 uploadChunk() 函数需要自己实现。
若传输中断,我们需要记录已传输的字节数到 resume.txt 文件,并使用 Deno.exit(1) 结束程序。在下次上传时,程序会检测是否存在 resume.txt 文件,若存在,则从记录的起始位置开始继续传输。在传输结束后,我们需要删除这个文件。
总结
在 Deno 中实现断点续传功能,主要是通过控制文件读写的起始位置来实现。在传输过程中,可以使用类似于 resume.txt 的文件记录已传输的字节数和传输起始时间。这种方案虽然可以实现断点续传功能,但是需要自己实现传输过程,对于传输过程中的错误处理需要自己处理。在实际生产环境中,建议使用第三方库或者框架来实现,更加稳定和可靠。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/64843bcc48841e989435e2bf