fs.statSync报错怎么办?

//删除文件夹
function delDir(path){
    var files = [];
    if(fs.existsSync(path)){
        files = fs.readdirSync(path);
        files.forEach((file, index) => {
            var curPath = path + "/" + file;
            if(fs.statSync(curPath).isDirectory()){
                delDir(curPath); //递归删除文件夹
            } else {
                try {
                    fs.unlinkSync(curPath); //删除文件
                } catch (error) {
                    console.log("删除出错:"+curPath);
                }
            }
        });
        try {
            fs.rmdirSync(path);
        } catch (error) {
            console.log("删除出错:"+path);
        }
        
    }
}

使用以上函数删除文件夹总是报错,很随机的,几天偶尔报一次,不知道什么原因,哪位大神帮忙看下,报错在fs.statSync的位置。

Error: EPERM: operation not permitted, stat 'D:/wwwroot/make/public_html/muban/app/data/files/make-1641644430211-8611702404657482.jpg'
    at Object.statSync (fs.js:1131:3)
    at D:\wwwroot\make\node\makehtmlexe\index.js:34:19
    at Array.forEach (<anonymous>)
    at delDir (D:\wwwroot\make\node\makehtmlexe\index.js:32:15)
    at IncomingMessage.<anonymous> (D:\wwwroot\make\node\makehtmlexe\index.js:572:7)
    at IncomingMessage.emit (events.js:412:35)
    at endReadableNT (internal/streams/readable.js:1334:12)
    at processTicksAndRejections (internal/process/task_queues.js:82:21) {
  errno: -4048,
  syscall: 'stat',
  code: 'EPERM',
  path: 'D:/wwwroot/make/public_html/muban/app/data/files/make-1641644430211-8611702404657482.jpg'
}

文件都是正常的jpg文件,报错后,再删再测试却又是正常的,不测试,又偶尔会出现一次,搞不懂哪里问题。

nodejs用的v14.18.1


2022-1-26:已找到问题原因,下载jpg时使用fs.createWriteStream创建了个0kb的文件,如果jpg下载失败,这个jpg将一直处于占用状态,是自己疏忽的原因,感谢各位大佬的解答!
阅读 4.3k
3 个回答

看这个报错是提示权限的问题
1:你运行node index.js 的时候使用的管理员的权限操作的吗?
2:执行程序的时候,操作的那个图片有没有被其他程序占用或者你有另外的一个程序也正在执行删除操作。

用的删文件夹方法与你代码逻辑一致
deleteFolder
唯一区别是我用for of来你用forEach
这边不负责任的猜测就是因为你用forEach引起的,即使内部是用同步Sync的fs方法,但是forEach是异步的,最后那个fs.rmdirSync(path);并不会等待内部全部删完了才执行。

在嵌套比较浅执行比较快的情况下,内部先删完才执行到后面没问题,但凡内部删的比较慢一点外面先执行就报错了。

forEach 本身不是异步的,但里面的业务过程可能是异步的,只有在使用 await 的时候容易判断失误。

fs.rmdirSync(path, { recursive: true, force: true }) 可以直接删除目录树,所以没必要自己写递归。

到于递归遇到的问题,有可能是系统的文件状态不正常造成的,比如使用了杀毒软件的时候,你去取某个目录的信息它会就锁住查杀,查杀不够快你在删除的时候文件就还在使用中。遇到这种情况可以稍等一下再尝试一次删除看看。当然使用同步代码处理起来可能会比较困难,因为 JavaScript 没有同步等待的语句。不过可以直接在 catch 块里立即再尝试 1~2 次看看,比如用这个来取状态

function tryGetState(path, times = 3) {
    for (let i = 0; i < times; i++) {
        try {
            return fs.statSync(path);
        } catch {
            continue;
        }
    }
    throw new Error("get state failed");
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题