feat(remote): 实现文件下载真实进度显示
- 下载改用流式读取,计算真实进度百分比 - 通过 IPC 事件实时推送进度到前端 - 支持 Content-Length 计算下载进度
This commit is contained in:
@@ -255,9 +255,9 @@ ipcMain.handle('remote-upload-file', async (_event, serverHost: string, port: nu
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('remote-download-file', async (_event, serverHost: string, port: number, fileName: string, remotePath: string, localPath: string, password?: string) => {
|
||||
ipcMain.handle('remote-download-file', async (_event, id: string, serverHost: string, port: number, fileName: string, remotePath: string, localPath: string, password?: string) => {
|
||||
try {
|
||||
log.info('Remote download params:', { serverHost, port, fileName, remotePath, localPath, password });
|
||||
log.info('Remote download params:', { id, serverHost, port, fileName, remotePath, localPath, password });
|
||||
|
||||
const win = electronState.getMainWindow();
|
||||
if (!win) {
|
||||
@@ -275,8 +275,12 @@ ipcMain.handle('remote-download-file', async (_event, serverHost: string, port:
|
||||
throw new Error(`Download failed: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const buffer = await response.arrayBuffer();
|
||||
const contentLength = response.headers.get('Content-Length');
|
||||
if (!contentLength) {
|
||||
throw new Error('Server did not return Content-Length');
|
||||
}
|
||||
|
||||
const totalSize = parseInt(contentLength, 10);
|
||||
const targetDir = localPath || 'C:\\';
|
||||
const targetPath = path.join(targetDir, fileName);
|
||||
|
||||
@@ -284,8 +288,31 @@ ipcMain.handle('remote-download-file', async (_event, serverHost: string, port:
|
||||
fs.mkdirSync(targetDir, { recursive: true });
|
||||
}
|
||||
|
||||
fs.writeFileSync(targetPath, Buffer.from(buffer));
|
||||
const fileStream = fs.createWriteStream(targetPath);
|
||||
const reader = response.body?.getReader();
|
||||
if (!reader) {
|
||||
throw new Error('Failed to get response body reader');
|
||||
}
|
||||
|
||||
let downloadedSize = 0;
|
||||
const CHUNK_SIZE = 64 * 1024;
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
downloadedSize += value.length;
|
||||
fileStream.write(value);
|
||||
|
||||
const progress = Math.round((downloadedSize / totalSize) * 100);
|
||||
win.webContents.send('download-progress', { id, progress });
|
||||
}
|
||||
}
|
||||
|
||||
fileStream.end();
|
||||
return { success: true, filePath: targetPath };
|
||||
} catch (error: any) {
|
||||
log.error('Remote download failed:', error);
|
||||
|
||||
Reference in New Issue
Block a user