Nodejs fs:貌似renameSync()文件时出错了

Nodejs fs:貌似renameSync()文件时出错了

<pre><code>function upload(response, request) { console.log(“Request handler ‘upload’ was called.”); var form = new formidable.IncomingForm(); console.log(“about to parse”); form.parse(request, function(error, fields, files) { console.log(“parsing done”); console.log(“F.U.P: “+files.upload.path); fs.renameSync(files.upload.path, “/tmp/test.png”); response.writeHead(200, {“Content-Type”: “text/html”}); response.write(“received image:<br/>”); response.write(”<img src=’/show’ />”); response.end(); }); } </code></pre>

<hr/>

<p>环境:win7、node.exe Ver 0.6.10</p>

<p>是因为权限问题吗?</p>

<hr/>

<p>运行报错:</p>

<pre><code>E:\cygwin\home\dd\dodo>node index.js

F.U.P: C:\Users\dd\AppData\Local\Temp\68ef963377b965f242cf7ae5b4595f31

fs.js:330 return binding.rename(pathModule._makeLong(oldPath), ^ Error: ENOENT, no such file or directory 'C:\Users\dd\AppData\Local\Temp\68ef9 377b965f242cf7ae5b4595f31’ at Object.renameSync (fs.js:330:18) at E:\cygwin\home\dd\dodo\requestHandlers.js:35:8 at IncomingForm.<anonymous> (E:\cygwin\home\dd\dodo\node_modules\formidabl lib\incoming_form.js:117:9) at IncomingForm.emit (events.js:64:17) at IncomingForm._maybeEnd (E:\cygwin\home\dd\dodo\node_modules\formidable
b\incoming_form.js:376:8) at E:\cygwin\home\dd\dodo\node_modules\formidable\lib\incoming_form.js:207 2 at E:\cygwin\home\dd\dodo\node_modules\formidable\lib\file.js:59:5 at Object.oncomplete (fs.js:1289:9)

E:\cygwin\home\dd\dodo> </code></pre>


22 回复

根据你提供的信息,错误发生在使用 fs.renameSync 方法重命名文件时。错误提示 ENOENT 表明目标文件或路径不存在。以下是一些可能的原因和解决方案:

可能的原因

  1. 源文件路径错误files.upload.path 可能不正确。
  2. 目标路径错误"/tmp/test.png" 在 Windows 系统上可能不正确。
  3. 权限问题:当前用户可能没有足够的权限来执行重命名操作。

解决方案

检查源文件路径

确保 files.upload.path 是正确的。可以通过打印该路径来验证。

console.log("Source path: " + files.upload.path);

修改目标路径

在 Windows 上,使用正确的路径格式。例如:

fs.renameSync(files.upload.path, "C:\\temp\\test.png");

检查权限

确保 Node.js 进程有足够的权限来访问和修改文件。可以尝试以管理员身份运行你的应用程序。

示例代码

下面是修正后的代码示例:

function upload(response, request) {
    console.log("Request handler 'upload' was called.");
    var form = new formidable.IncomingForm();
    console.log("about to parse");
    form.parse(request, function(error, fields, files) {
        if (error) {
            console.error("Error parsing form:", error);
            response.writeHead(500, {"Content-Type": "text/plain"});
            response.end("Internal Server Error");
            return;
        }
        
        console.log("parsing done");
        console.log("F.U.P: " + files.upload.path);

        // 修改目标路径
        const targetPath = "C:\\temp\\test.png";
        try {
            fs.renameSync(files.upload.path, targetPath);
            console.log(`File moved from ${files.upload.path} to ${targetPath}`);
        } catch (err) {
            console.error("Error moving file:", err);
            response.writeHead(500, {"Content-Type": "text/plain"});
            response.end("Failed to move file");
            return;
        }

        response.writeHead(200, {"Content-Type": "text/html"});
        response.write("received image:<br/>");
        response.write("<img src='/show' />");
        response.end();
    });
}

总结

通过检查路径和权限问题,你可以解决 fs.renameSync 方法的错误。确保路径正确,并且目标路径在 Windows 上使用正确的格式。如果问题仍然存在,考虑以管理员权限运行你的 Node.js 应用程序。


ENOENT 文件不存在 ,看看formidable临时文件写成功没?

另外文件同步操作得try{}catch(e){},要不然异常会导致进程直接退出

我看到临时文件夹里有上传的文件。 我参照的例子是: http://nodebeginner.org/index-zh-cn.html 上文贴出的是其中的最后一段代码。

请指教~

fs.renameSync这个方法没有问题的,应该是你其他地方写错了

fs.rename 之前遇到过类似的问题,临时文件写成功了,但是就是无法移动… 猜测是由于磁盘分区导致的,你的例子中也符合这个条件 C: -> E:

改变formidable的默认零时文件夹路径,保证和目标目录处于同一个磁盘分区 formidable.IncomingForm.UPLOAD_DIR = your_path

这样应该ok的

function upload(response, request) {
  console.log("Request handler 'upload' was called.");
  var form = new formidable.IncomingForm();
  form.uploadDir = "tmp"
 // console.log("about to parse");
  form.parse(request, function(error, fields, files) {
    //console.log("parsing done");
	console.log("F.U.P: " + files.upload.path);
	setTimeout(function(){
	try{
	    fs.renameSync(files.upload.path, "tmp/test.png");
	}catch(e){
		console.log(e);
	}
    response.writeHead(200, {"Content-Type": "text/html"});
    response.write("received image:<br/>");
    response.write("<img src='/show' />");
    response.end();
	},1000
	);
  });
}

搞定了。谢谢你~

another reply: https://groups.google.com/group/nodejs/browse_thread/thread/222cb0fd30906d4e

我也碰到了这个问题,windows上会有。按照fish的方法解决了,只要在工程目录下建个目录A,然后把formidable的uploadDir指向这个目录(相对路径即可),就能使用这个目录了。

我也遇到了这个问题。多谢指点,开始开到错误提示“文件或者目录不存在”,而且打印出的路径是指向C盘,将感到奇怪。现在搞定了,3Q。

将fs.renameSync(files.upload.path, “/tmp/test.png”);中的"/tmp/test.png"改为 "./tmp/test.png"也是可以的。我就是这么改的。

在Windows上尽量不要操作C盘,权限问题很麻烦的

我在winxp+node0.6下测试,你的这个方法出错,错误提示与楼主的类似

fs.rename()不能跨磁盘移动文件 renameSync 不能创建新目录 参考 http://stackoverflow.com/questions/10084000/why-use-nodejs-upload-exception

/home/hd-user/github/nodejs-beginner/requestHandlers.js:61
    console.log(files.upload.path);
                            ^
TypeError: Cannot read property 'path' of undefined

这个错误大概什么原因呢?

正解啊

你的例子中的upload()是不是该过啊,files.upload.path 中的path 应该和请求路径的pathname 一致的

我也照抄的,这里的问题改了下,手动创建了tmp文件。 代码如下:

// 响应upload
var upload = function(response, request) {
    console.log('Request handler "upload" was called.');
    var form=new formidable.IncomingForm();
    console.log('about to parse');
// 写一个临时路径
form.uploadDir='tmp';
form.parse(request,function(err,fields,files){
    console.log('parsing done');
    console.log(files.upload);
    // 同步操作文件,需要try catch
    try{
        fs.renameSync(files.upload.path,'tmp/test.png');
    }catch(e){
        console.log(e);
    }
    
    response.writeHead(200,{'Content-Type':'text/html'});
    response.write('received img:&lt;/br&gt;');
    response.write('&lt;a href="/show"&gt;&lt;img src="/show" /&gt;&lt;/a&gt;');
    response.end();
});

}; // 显示文件 var show=function(response){ console.log(‘request handler “upload” was called’); fs.readFile(’./tmp/test.png’,‘binary’,function(err,file){ if(err){ response.writeHead(500,{‘Content-Type’:‘text/plain’}); response.write(err+’\n’); response.end(); }else{ response.writeHead(200,{‘Content-Type’:‘image/png’}); response.write(file,‘binary’); response.end(); } }); };

upload接口,更改了输出的html结构:response.write(’<a href="/show"><img src="/show" /></a>’); 不然在windows图片无法显示。 show接口,fs.readFile(’./tmp/test.png’)多了一个’./’,我还不知道这个是啥意思。 若不加的话,报错信息提示,位置是在:f:\tmp\test.png。估计加了’./'就在当前目录下寻找文件了。

/* Possible error on Windows systems: tried to rename to an already existing file */ fs.rename(files.upload.path, “/tmp/test.png”, function(err) { if (err) { fs.unlink("/tmp/test.png"); fs.rename(files.upload.path, “/tmp/test.png”); } });

我也出现同样的的错误,已经按照大家的办法解决了,谢谢

从错误信息来看,fs.renameSync() 函数尝试将一个不存在的文件进行重命名操作。具体来说,路径 C:\Users\dd\AppData\Local\Temp\68ef963377b965f242cf7ae5b4595f31 似乎是一个临时文件,可能因为某种原因被删除或移动了。

示例代码

为了调试这个问题,你可以增加一些日志输出来检查文件路径是否存在:

const fs = require('fs');
const path = require('path');

function upload(response, request) {
    console.log("Request handler 'upload' was called.");
    var form = new formidable.IncomingForm();
    console.log("about to parse");

    form.parse(request, function(error, fields, files) {
        if (error) {
            console.error("Error parsing form:", error);
            return;
        }
        
        const oldPath = files.upload.path;
        const newPath = "/tmp/test.png";

        // Check if the old path exists
        if (!fs.existsSync(oldPath)) {
            console.error(`Source file does not exist: ${oldPath}`);
            response.writeHead(500, {"Content-Type": "text/html"});
            response.write("Error: Source file does not exist.");
            response.end();
            return;
        }

        try {
            fs.renameSync(oldPath, newPath);
            console.log("File renamed successfully.");
        } catch (err) {
            console.error("Error renaming file:", err);
            response.writeHead(500, {"Content-Type": "text/html"});
            response.write("Error: " + err.message);
            response.end();
        }

        response.writeHead(200, {"Content-Type": "text/html"});
        response.write("Received image:<br/>");
        response.write("<img src='/show' />");
        response.end();
    });
}

解释

  1. 检查文件是否存在:使用 fs.existsSync(oldPath) 检查源文件是否真的存在。
  2. 错误处理:如果源文件不存在,则返回错误信息给客户端,并记录错误日志。
  3. 日志输出:添加更多的日志输出以帮助诊断问题。

通过这些步骤,你可以更好地理解问题发生的原因,并确定是文件路径问题还是其他潜在问题。

回到顶部