Compare commits

..

No commits in common. "eeff7271a141247e27db6bf09bdeeac2dc7873ac" and "a4f40785519704fbb6a01b45633fedf8dcad7909" have entirely different histories.

View File

@ -119,40 +119,60 @@ class SFTPService {
try { try {
({ conn, sftp } = await this.createConnection(hostConfig)); ({ conn, sftp } = await this.createConnection(hostConfig));
const filename = path.basename(remotePath);
const self = this;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 使用 fastGet 方法进行下载,更加可靠 // 获取文件大小
sftp.fastGet(remotePath, localPath, { sftp.stat(remotePath, (err, stats) => {
concurrency: 1, // 单线程下载,更稳定
chunkSize: 32768, // 32KB 块大小
step: function (transferred, chunk, total) {
const percent = Math.round((transferred / total) * 100);
if (self.progressCallback) {
self.progressCallback({
type: 'download',
filename,
percent,
transferred,
total,
});
}
}
}, (err) => {
conn.end();
if (err) { if (err) {
// 删除可能不完整的文件 conn.end();
try {
fs.unlinkSync(localPath);
} catch (e) {
// 忽略删除失败
}
reject(err); reject(err);
return; return;
} }
const totalSize = stats.size;
let downloadedSize = 0;
const filename = path.basename(remotePath);
// 创建读写流
const readStream = sftp.createReadStream(remotePath);
const writeStream = fs.createWriteStream(localPath);
readStream.on('data', (chunk) => {
downloadedSize += chunk.length;
const percent = Math.round((downloadedSize / totalSize) * 100);
if (this.progressCallback) {
this.progressCallback({
type: 'download',
filename,
percent,
transferred: downloadedSize,
total: totalSize,
});
}
});
readStream.on('error', (err) => {
writeStream.destroy();
conn.end();
fs.unlink(localPath, () => { });
reject(err);
});
writeStream.on('error', (err) => {
readStream.destroy();
conn.end();
fs.unlink(localPath, () => { });
reject(err);
});
// 使用 'finish' 事件确保数据完全写入磁盘
writeStream.on('finish', () => {
conn.end();
resolve({ success: true, localPath }); resolve({ success: true, localPath });
}); });
readStream.pipe(writeStream);
});
}); });
} catch (err) { } catch (err) {
return { success: false, error: err.message }; return { success: false, error: err.message };
@ -167,34 +187,50 @@ class SFTPService {
try { try {
({ conn, sftp } = await this.createConnection(hostConfig)); ({ conn, sftp } = await this.createConnection(hostConfig));
const filename = path.basename(localPath);
const self = this;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// 使用 fastPut 方法进行上传,更加可靠 const stats = fs.statSync(localPath);
sftp.fastPut(localPath, remotePath, { const totalSize = stats.size;
concurrency: 1, // 单线程上传,更稳定 let uploadedSize = 0;
chunkSize: 32768, // 32KB 块大小 const filename = path.basename(localPath);
step: function (transferred, chunk, total) {
const percent = Math.round((transferred / total) * 100); // 创建读写流
if (self.progressCallback) { const readStream = fs.createReadStream(localPath);
self.progressCallback({ const writeStream = sftp.createWriteStream(remotePath);
readStream.on('data', (chunk) => {
uploadedSize += chunk.length;
const percent = Math.round((uploadedSize / totalSize) * 100);
if (this.progressCallback) {
this.progressCallback({
type: 'upload', type: 'upload',
filename, filename,
percent, percent,
transferred, transferred: uploadedSize,
total, total: totalSize,
}); });
} }
} });
}, (err) => {
readStream.on('error', (err) => {
writeStream.destroy();
conn.end(); conn.end();
if (err) {
reject(err); reject(err);
return; });
}
writeStream.on('error', (err) => {
readStream.destroy();
conn.end();
reject(err);
});
// 使用 'finish' 事件确保数据完全写入
writeStream.on('finish', () => {
conn.end();
resolve({ success: true, remotePath }); resolve({ success: true, remotePath });
}); });
readStream.pipe(writeStream);
}); });
} catch (err) { } catch (err) {
return { success: false, error: err.message }; return { success: false, error: err.message };