const fs = require("fs"); const { Transform } = require('stream'); const { pipeline } = require('node:stream/promises'); const paths = require('path'); function convertBytes(bytes) { if (bytes >= 1024 * 1024 * 1024) { const gigabytes = bytes / (1024 * 1024 * 1024); return `${gigabytes.toFixed(2)}GB`; } else if (bytes >= 1024 * 1024) { const megabytes = bytes / (1024 * 1024); return `${megabytes.toFixed(2)}MB`; } else if (bytes >= 1024 ) { const megabytes = bytes / (1024 ); return `${megabytes.toFixed(2)}KB`; } else { return `${bytes} B`; } } // 创建一个用于统计字节数的Transform流 class ByteCounter extends Transform { constructor(totalSize) { super(); this.bytesCount = 0; this.totalSize = totalSize; this.timestamp = (new Date()).getTime() this.recordBytesCount = 0; this.speed = 0; this.intervalId = setInterval(()=>{ let now = (new Date()).getTime() let timecost = now - this.timestamp; this.speed = ((this.bytesCount - this.recordBytesCount ) * 1000 / timecost).toFixed(2) this.timestamp = now; this.recordBytesCount = this.bytesCount; }, 2000); } _transform(chunk, encoding, callback) { this.bytesCount += chunk.length; let process = (this.bytesCount * 100 / this.totalSize).toFixed(2) console.log(`进度 ${process}%\t速度${ convertBytes(this.speed) }/s\t${convertBytes(this.bytesCount)} / ${convertBytes(this.totalSize)}`); callback(null, chunk); } _flush(callback) { if (this.intervalId) { clearInterval(this.intervalId); } callback(); } } async function wUpload(client , from, to){ const totalSize = fs.statSync(from).size; const rs = fs.createReadStream( from ); let wSize = 0; let rSize = 0; rs.on("data", (r)=>{ rSize += r.length; console.log("r", rSize * 100 / totalSize) }) const ws = client.createWriteStream(to) ws.on("data", (r)=>{ wSize += r.length; console.log("w", wSize * 100 / totalSize) }) ws.on("finish", ()=>{ console.log("finish") }) return pipeline( rs, ws ); } /** * 文件不存在会抛出异常 * @param client * @param file * @param to * @returns {Promise} */ async function wDownload(client, file, to){ // 确认文件存在以及大小 let stat = await client.stat(file); let totalSize = stat.size; if ( ! to ) { to = paths.basename(file); } const byteCounter = new ByteCounter(totalSize); await pipeline( client.createReadStream(file), byteCounter, fs.createWriteStream(to) ); await pipeline(rs , ws ); } async function main(){ const webdav = await import("webdav"); // const client = webdav.createClient( // "http://baishe.fullstack.club:5244/dav", // { // username: "cheney", // password: "722V587" // } // ); const client = webdav.createClient( "http://172.16.18.45:5244/dav", { username: "kit", password: "kitkit" } ); // Get directory contents const directoryItems = await client.getDirectoryContents("/"); console.log(directoryItems) // 下载测试 await wDownload(client, "/kit") // let rs = fs.createReadStream("D:\\fullstack\\TDevOps\\kit\\dist\\windows\\kit.exe") // rs.on("data", (r)=>{ // console.log("r", r.length) // }) // let stat = await client.stat("/kitw.exe"); // console.log("stat", stat) // let ws = client.createWriteStream( // "/kit.exe" // ); // ws.on("data", (r)=>{ // console.log("w", r.length) // }) // console.log("end") // await wUpload( client, "./kit", "/kit" ) // await wUpload( client, "../dist/windows/kit.exe", "/modules/kit/0.1.20240227094429/Windows/X86_64/kit.exe" ) console.log("over") } main()