Thread overview
Copying and moving directories
Feb 16, 2017
Chris
Feb 16, 2017
Adam D. Ruppe
Feb 16, 2017
Chris
Feb 16, 2017
Jonathan M Davis
Feb 17, 2017
Kagamin
Feb 17, 2017
Jonathan M Davis
Feb 17, 2017
Chris
Feb 17, 2017
Jonathan M Davis
Feb 17, 2017
Chris
Feb 17, 2017
Daniel Kozák
February 16, 2017
In `std.file`, I haven't found a function that allows me to move or at least copy directories, as in `mv dir /toDir`. Do I have to go the awkward way over `rename` or something?
February 16, 2017
On Thursday, 16 February 2017 at 16:38:51 UTC, Chris wrote:
> In `std.file`, I haven't found a function that allows me to move or at least copy directories, as in `mv dir /toDir`. Do I have to go the awkward way over `rename` or something?

Have you already tried just renaming the directory?
February 16, 2017
On Thursday, 16 February 2017 at 16:41:48 UTC, Adam D. Ruppe wrote:
> On Thursday, 16 February 2017 at 16:38:51 UTC, Chris wrote:
>> In `std.file`, I haven't found a function that allows me to move or at least copy directories, as in `mv dir /toDir`. Do I have to go the awkward way over `rename` or something?
>
> Have you already tried just renaming the directory?

Yes, but that's a bit awkward. It'd be handier to have a function like `mv(dir, toDir)`.
February 16, 2017
On Thursday, February 16, 2017 16:47:05 Chris via Digitalmars-d-learn wrote:
> On Thursday, 16 February 2017 at 16:41:48 UTC, Adam D. Ruppe
>
> wrote:
> > On Thursday, 16 February 2017 at 16:38:51 UTC, Chris wrote:
> >> In `std.file`, I haven't found a function that allows me to move or at least copy directories, as in `mv dir /toDir`. Do I have to go the awkward way over `rename` or something?
> >
> > Have you already tried just renaming the directory?
>
> Yes, but that's a bit awkward. It'd be handier to have a function
> like `mv(dir, toDir)`.

Well, there's zero difference between renaming the file or directory and moving it. It's simply a difference in name. rename actually comes from POSIX, where rename is used in C code, and mv is used in the shell. So, I guess that you can blame POSIX. But there really isn't any reason to have a mv or move function in addition to rename.

If you want mv instead, just alias rename to mv.

However, I would point out that rename has the problem (at least on *nix - not sure about Windows) that it can't move across filesystem boundaries. I think that at some point, an alternative which did work across filesystem boundaries was proposed, and that may have been called move. It's not currently in Phobos though.

- Jonathan M Davis

February 17, 2017
V Thu, 16 Feb 2017 16:38:51 +0000
Chris via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
napsáno:

> In `std.file`, I haven't found a function that allows me to move or at least copy directories, as in `mv dir /toDir`. Do I have to go the awkward way over `rename` or something?

http://forum.dlang.org/post/uzoxwrxsgeazugqohusp@forum.dlang.org

February 17, 2017
On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis wrote:
> Well, there's zero difference between renaming the file or directory and moving it. It's simply a difference in name.

Isn't there a difference?
I though
move("/path/dir1","dir2") moves folder to current directory and changes its name to dir2
rename("/path/dir1","dir2") leaves folder where it was and only changes its name to dir2
February 17, 2017
On Friday, February 17, 2017 08:48:03 Kagamin via Digitalmars-d-learn wrote:
> On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis
>
> wrote:
> > Well, there's zero difference between renaming the file or directory and moving it. It's simply a difference in name.
>
> Isn't there a difference?
> I though
> move("/path/dir1","dir2") moves folder to current directory and
> changes its name to dir2
> rename("/path/dir1","dir2") leaves folder where it was and only
> changes its name to dir2

No, rename does change the whole path, just like mv would. If you want to just change the last part of the path, then you need to supply the entire path again but just change the last part. e.g. this passes:

import std.file;

void main()
{
    scope(exit) if("a".exists) rmdirRecurse("a");
    scope(exit) if("c".exists) rmdirRecurse("c");

    mkdirRecurse("a/b");
    assert("a".exists);
    assert(!"c".exists);
    assert("a/b".exists);
    assert(!"a/c".exists);

    rename("a/b", "c");
    assert("a".exists);
    assert("c".exists);
    assert(!"a/b".exists);
    assert(!"a/c".exists);
}

Maybe there's another language that declares a move function and a rename function like you describe, but POSIX has rename for C and mv for shell, and both of them change the whole path, and on POSIX systems, D has just wrapped the POSIX rename function, so its behavior is the same.

http://www.unix.com/man-page/FreeBSD/2/rename/ https://linux.die.net/man/2/rename

- Jonathan M Davis

February 17, 2017
On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis wrote:
>
> Well, there's zero difference between renaming the file or directory and moving it. It's simply a difference in name. rename actually comes from POSIX, where rename is used in C code, and mv is used in the shell. So, I guess that you can blame POSIX. But there really isn't any reason to have a mv or move function in addition to rename.

`mv` or `move` would be more intuitive. I actually looked for names similar to the operations available in the shell (cp/copy, mv/move). It took me a few minutes to realize I had to use `rename` (which is poorly documented). But it is counter-intuitive. When you use a GUI, `rename` doesn't change the location. `rename` is a bit "techy", you have to go "wait a minute, when you think about it, rename should do the same". But that's not good enough for a library function. One of D's slogans is `simple things should be simple`, so moving a file should be `move(dir, toDir)`. Seriously, you don't want to spend much time on stuff like that.

> If you want mv instead, just alias rename to mv.
>
> However, I would point out that rename has the problem (at least on *nix - not sure about Windows) that it can't move across filesystem boundaries. I think that at some point, an alternative which did work across filesystem boundaries was proposed, and that may have been called move. It's not currently in Phobos though.
>
> - Jonathan M Davis

That is actually a bit of a problem. First, I might want to store backup files on a different device. Second, loads of applications need this nowadays to interact with MP3 players, ebook readers etc.
February 17, 2017
On Friday, February 17, 2017 11:00:30 Chris via Digitalmars-d-learn wrote:
> On Thursday, 16 February 2017 at 17:06:30 UTC, Jonathan M Davis
>
> wrote:
> > Well, there's zero difference between renaming the file or directory and moving it. It's simply a difference in name. rename actually comes from POSIX, where rename is used in C code, and mv is used in the shell. So, I guess that you can blame POSIX. But there really isn't any reason to have a mv or move function in addition to rename.
>
> `mv` or `move` would be more intuitive. I actually looked for names similar to the operations available in the shell (cp/copy, mv/move). It took me a few minutes to realize I had to use `rename` (which is poorly documented). But it is counter-intuitive. When you use a GUI, `rename` doesn't change the location. `rename` is a bit "techy", you have to go "wait a minute, when you think about it, rename should do the same". But that's not good enough for a library function. One of D's slogans is `simple things should be simple`, so moving a file should be `move(dir, toDir)`. Seriously, you don't want to spend much time on stuff like that.

Well, there's a _long_ history of it being called rename on POSIX systems, and since the D function is a simple wrapper around rename, it makes sense that it's called rename, much as I agree that the name isn't the best for anyone not familiar with the C function. Regardless, changing it now would break code, and at this point, we pretty much never rename public symbols in Phobos just to improve their names.

> > If you want mv instead, just alias rename to mv.
> >
> > However, I would point out that rename has the problem (at least on *nix - not sure about Windows) that it can't move across filesystem boundaries. I think that at some point, an alternative which did work across filesystem boundaries was proposed, and that may have been called move. It's not currently in Phobos though.
>
> That is actually a bit of a problem. First, I might want to store backup files on a different device. Second, loads of applications need this nowadays to interact with MP3 players, ebook readers etc.

Yes, it is a problem, but we would have to implement our own function to do it, because the underlying system calls don't support moving files across filesystem boundaries. At that point, what you're fundamentally doing is copying the file or directory and then deleting the original. It's not actually possible to simply move files across filesystem boundaries (which is why the system call works the way it does). Any language or library which supports moving across file system boundaries implemented its own solution rather than simply using a system call.

And we probably should add some sort of move function to std.file that works more like mv (leaving rename to wrap the system call and act like someone familiar with the POSIX function would expect while providing a more user-friendly - but somewhat less efficient - function for moving files from anywhere to anywhere), but thus far, no one has added such a function to Phobos. We don't even have one that copies recursively (there's a PR in limbo for that one, but there were issues with the implementation and disagreement on how it should work - I basically wanted it to act like cp - which the PR doesn't - whereas others thought that that was a terrible idea). So, while what std.file has is nice and cross-platform and more pleasant than dealing with the underlying system calls even when you don't care about being cross-platform, it could definitely use some work to make some aspects of it more user-friendly. Most of what is there are fairly thin wrappers around systems calls.

Sadly, my workaround has generally been to use std.process to use cp or mv, but there are also plenty of cases where I would have had to do that anyway, because I needed sudo (which AFAIK can't be done without the shell - though I'd love to learn how if it is).

- Jonathan M Davis

February 17, 2017
On Friday, 17 February 2017 at 11:40:35 UTC, Jonathan M Davis wrote:
>
> Well, there's a _long_ history of it being called rename on POSIX systems, and since the D function is a simple wrapper around rename, it makes sense that it's called rename, much as I agree that the name isn't the best for anyone not familiar with the C function. Regardless, changing it now would break code, and at this point, we pretty much never rename public symbols in Phobos just to improve their names.

Nobody wants to rename `rename` :-) But an additional `move` function would be nice.

>
> [...]

I agree. std.file needs more work.