node实现大文件断点上传
时间: 2024-01-01 20:05:13 浏览: 31
大文件的断点上传主要是利用HTTP协议的Range请求头来实现,其中Range请求头用于指定请求的数据范围,可以用于服务器响应部分内容或者支持分块下载。通过Range请求头,客户端可以在上传文件时只上传文件的某个部分,或者在上传过程中出现中断后可以继续从中断处继续上传。
以下是用Node.js实现大文件断点上传的示例代码:
```javascript
const fs = require('fs');
const http = require('http');
const FILE_PATH = '/path/to/large/file';
const PORT = 3000;
const server = http.createServer((req, res) => {
if (req.url === '/upload') {
const range = req.headers.range;
if (range) {
const parts = range.replace(/bytes=/, '').split('-');
const start = parseInt(parts[0], 10);
const end = parts[1] ? parseInt(parts[1], 10) : fs.statSync(FILE_PATH).size - 1;
const chunkSize = (end - start) + 1;
const fileStream = fs.createReadStream(FILE_PATH, { start, end });
res.writeHead(206, {
'Content-Range': `bytes ${start}-${end}/${fs.statSync(FILE_PATH).size}`,
'Accept-Ranges': 'bytes',
'Content-Length': chunkSize,
'Content-Type': 'application/octet-stream'
});
fileStream.pipe(res);
} else {
const fileStream = fs.createReadStream(FILE_PATH);
res.writeHead(200, {
'Content-Length': fs.statSync(FILE_PATH).size,
'Content-Type': 'application/octet-stream'
});
fileStream.pipe(res);
}
}
});
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
});
```
在客户端实现文件上传时,需要分段上传每个文件分片,并记录当前上传进度。如果上传过程中出现中断,可以记录已上传的分片,下次继续上传时从中断处继续上传。以下是客户端实现文件上传的示例代码:
```javascript
const fs = require('fs');
const http = require('http');
const path = require('path');
const FILE_PATH = '/path/to/large/file';
const CHUNK_SIZE = 1024 * 1024; // 1MB
const PORT = 3000;
let uploadedBytes = 0;
let totalBytes = fs.statSync(FILE_PATH).size;
let fileStream;
const uploadChunk = (start, end) => {
const options = {
hostname: 'localhost',
port: PORT,
path: '/upload',
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',
'Content-Length': end - start + 1,
'Content-Range': `bytes ${start}-${end}/${totalBytes}`
}
};
const req = http.request(options, (res) => {
if (res.statusCode === 200 || res.statusCode === 206) {
uploadedBytes += end - start + 1;
console.log(`Uploaded ${uploadedBytes} bytes of ${totalBytes} bytes`);
if (uploadedBytes === totalBytes) {
console.log('Upload complete!');
} else {
uploadNextChunk();
}
} else {
console.error(`Error uploading chunk ${start}-${end}: ${res.statusCode} ${res.statusMessage}`);
}
});
fileStream.pipe(req);
};
const uploadNextChunk = () => {
if (uploadedBytes === totalBytes) {
return;
}
const start = uploadedBytes;
const end = Math.min(start + CHUNK_SIZE - 1, totalBytes - 1);
console.log(`Uploading chunk ${start}-${end}`);
fileStream = fs.createReadStream(FILE_PATH, { start, end });
uploadChunk(start, end);
};
const startUpload = () => {
console.log(`Starting upload of ${path.basename(FILE_PATH)} (${totalBytes} bytes)`);
uploadNextChunk();
};
startUpload();
```
注意,以上代码只是示例代码,实际项目中还需要考虑错误处理、性能优化、安全性等问题。