mirror of
https://github.com/jprichardson/node-fs-extra.git
synced 2026-02-01 17:21:13 +00:00
Refactor copy to use opendir (#1028)
* refactor(copy): backport https://github.com/nodejs/node/pull/41351 * perf(copy): parallel copy * perf(copy): run filter in parallel as well
This commit is contained in:
parent
acf5585558
commit
1d931c88b2
@ -106,7 +106,17 @@ function mkDirAndCopy (srcMode, src, dest, opts) {
|
||||
}
|
||||
|
||||
function copyDir (src, dest, opts) {
|
||||
fs.readdirSync(src).forEach(item => copyDirItem(item, src, dest, opts))
|
||||
const dir = fs.opendirSync(src)
|
||||
|
||||
try {
|
||||
let dirent
|
||||
|
||||
while ((dirent = dir.readSync()) !== null) {
|
||||
copyDirItem(dirent.name, src, dest, opts)
|
||||
}
|
||||
} finally {
|
||||
dir.closeSync()
|
||||
}
|
||||
}
|
||||
|
||||
function copyDirItem (item, src, dest, opts) {
|
||||
|
||||
@ -113,23 +113,28 @@ async function onDir (srcStat, destStat, src, dest, opts) {
|
||||
await fs.mkdir(dest)
|
||||
}
|
||||
|
||||
const items = await fs.readdir(src)
|
||||
const promises = []
|
||||
|
||||
// loop through the files in the current directory to copy everything
|
||||
await Promise.all(items.map(async item => {
|
||||
const srcItem = path.join(src, item)
|
||||
const destItem = path.join(dest, item)
|
||||
for await (const item of await fs.opendir(src)) {
|
||||
const srcItem = path.join(src, item.name)
|
||||
const destItem = path.join(dest, item.name)
|
||||
|
||||
// skip the item if it is matches by the filter function
|
||||
const include = await runFilter(srcItem, destItem, opts)
|
||||
if (!include) return
|
||||
promises.push(
|
||||
runFilter(srcItem, destItem, opts).then(include => {
|
||||
if (include) {
|
||||
// only copy the item if it matches the filter function
|
||||
return stat.checkPaths(srcItem, destItem, 'copy', opts).then(({ destStat }) => {
|
||||
// If the item is a copyable file, `getStatsAndPerformCopy` will copy it
|
||||
// If the item is a directory, `getStatsAndPerformCopy` will call `onDir` recursively
|
||||
return getStatsAndPerformCopy(destStat, srcItem, destItem, opts)
|
||||
})
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
const { destStat } = await stat.checkPaths(srcItem, destItem, 'copy', opts)
|
||||
|
||||
// If the item is a copyable file, `getStatsAndPerformCopy` will copy it
|
||||
// If the item is a directory, `getStatsAndPerformCopy` will call `onDir` recursively
|
||||
return getStatsAndPerformCopy(destStat, srcItem, destItem, opts)
|
||||
}))
|
||||
await Promise.all(promises)
|
||||
|
||||
if (!destStat) {
|
||||
await fs.chmod(dest, srcStat.mode)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user