This repository has been archived by the owner. It is now read-only.

fs.rename() can't move file between two different disks #2703

Closed
fishbar opened this Issue Feb 6, 2012 · 7 comments

Comments

Projects
None yet
5 participants
@fishbar

fishbar commented Feb 6, 2012

when upload file using formiddle module ,as default posted file will be written to a tmp dir(/tmp/xxxxx.file) . in my response handler, i want move this tmp file to apps storage path using fs.rename() . but fs.rename() always throw exception(can not find the source file: /tmp/xxxx.file) .

so i changed the formiddle module's default tmp folder into same disk with apps ,now it's works well

os: windows | linux ubuntu
node:v0.6.8

@Mithgol

This comment has been minimized.

Mithgol commented Feb 6, 2012

The same happens in Node.js v0.6.10, see the screenshot:

the screenshot

@TooTallNate

This comment has been minimized.

TooTallNate commented Feb 6, 2012

Someone correct me if I'm wrong, by I believe that's Just How It Works™. Since the fs module is almost 1-1 matchups to their C counterparts, that's just how the low-level rename(2) function works. For example, the high-level mv command first tries rename(2), then falls back on creating a copy of the original to the target then deleting the original if that fails. So you'll have to write a higher level cp() function or something that does just that.

The UNKNOWN error is a bug though, that should be EXDEV.

TooTallNate added a commit to TooTallNate/libuv that referenced this issue Feb 6, 2012

Add EXDEV to the errno map.
Fixes the "UNKNOWN" errno first reported in nodejs/node-v0.x-archive#2703.
@chjj

This comment has been minimized.

chjj commented Feb 6, 2012

Someone correct me if I'm wrong, by I believe that's Just How It Works™.

This. I don't know if there is an OS that would let you rename across filesystems. You have to copy the data and delete the old file. Rename just changes the link, it can't actually move data from one place to another.

@Mithgol

This comment has been minimized.

Mithgol commented Feb 6, 2012

PHP's rename() can rename across Unix partitions (since PHP 4.3.3) and across Windows drives (since PHP 5.3.1), and I guess that is why some people will inevitably try using Node's function in similar ways.

If we no one is going to extend fs.rename() and fs.renameSync(), then there should be some fs.mv() and fs.mvSync() to act like the high-level mv (and even, most likely, to be used instead of their rename counterparts in most cases: it's easier then making the JavaScript guess about drives and partitions).

@chjj

This comment has been minimized.

chjj commented Feb 6, 2012

I disagree. If you're adding a mv that's going to work no matter what, and can recursively move files across file systems if need be (and it would have to be recursive to match behavior of rename()'ing a directory), you're up to you ears in code. You're essentially writing an implementation of cp -r and a rm -rf as well. On top of that, you have to write a sync and an async version of each.

Node is supposed to be low level.

@indutny

This comment has been minimized.

Member

indutny commented Feb 6, 2012

Fully agreed with the @chjj and @TooTallNate point. rename() is a atomic and low-level.

High-level implementation may be done ( and probably is already done) in user-land modules and should not go into the core.

@indutny indutny closed this Feb 6, 2012

@Mithgol

This comment has been minimized.

Mithgol commented Feb 6, 2012

Note to future self: node-fs-extra has its implementation of rm -rf and a file copier (but the latter is not recursive). Has five dependencies.

claudyus added a commit to claudyus/share that referenced this issue Apr 21, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.