2

How do you move a file from one location to another using a C++ program in Linux? I've written a program to do this and it runs, but when I try to move a file to a different directory it doesn't move the file, I get the error message from the cout statement. When I try to just rename the file, moving it to the same directory with a new name it works. How can I fix my code so it will be able to move files to another directory?

Here's the code I've written:

#include <iostream>
#include <stdio.h>
using namespace std;

int main ()
{
  int result=1;
  char oldname[500];
  char newname[500];
  cout << "Enter the name of a file you want to move (include directory structure)";
  cin >> oldname;
  cout << "Enter the new location (include directory structure)";
  cin >> newname;

  result = rename( oldname , newname );
  if ( result == 0 )
    cout << "File successfully moved" << endl;
  else
    cout << "Error moving file" << endl;
  return 0;
}

Edit: I added perror to my code and the error message displayed is "Error moving file: No such file or directory" even though the directory I tried moving it to does exist and it has create and delete files permissions.

softengstu
  • 57
  • 1
  • 12
  • Wahtever you are trying to do, first try it on terminal with `rename` command. Once you are able to succeed with it then you can try doing the same thing with a program – Sandeep Jan 28 '18 at 22:50
  • Look at these answers: https://stackoverflow.com/questions/22201663/find-and-move-files-in-c – Quassel Kasper Jan 28 '18 at 22:52
  • [this](https://stackoverflow.com/questions/20161243/how-to-move-file-from-one-folder-to-different-folder-in-linux) answer might give you a little more insight. – Paul Rooney Jan 28 '18 at 22:54
  • I can't believe someone needs to ask this: what exactly do you type in for `oldname`? What does `ls -l` say for that string? Same for `newname`. – Michael Burr Jan 28 '18 at 23:27
  • the `rename` function does **not** create directories. So, you'd better create them yourself before moving. – Serge Jan 28 '18 at 23:48
  • @Serge I wasn't trying to use rename to create any directories - just to move the file from one directory to another one. Both directories exist before I run the program. – softengstu Jan 28 '18 at 23:53
  • your message either tells you that your source file does not exist or that your output directory does not exist. could probably be a permission issue. is your output directory writable by you? is your source file readable? – Serge Jan 28 '18 at 23:58
  • @MichaelBurr You were rude. This is my first time using Linux and this a place for people of all skill levels to ask questions. Your suggestion to check ls -l was helpful and I found the original file I was trying to move wasn't listed so I moved a file listed and it worked. – softengstu Jan 29 '18 at 00:00
  • @Serge I found that the source file didn't exist, though checking [ ! -f directory/filename ] showed that it did exist. I guess I did something wrong there but it worked with a different file. – softengstu Jan 29 '18 at 00:04
  • [How to move file from one folder to different folder in linux](https://stackoverflow.com/q/20161243/608639), [Moving a file on Linux in C](https://stackoverflow.com/q/17438493/608639), [Faster way to move file in c++ on linux](https://stackoverflow.com/q/19565085/608639), [Moving files from one directory into another](https://stackoverflow.com/q/42535318/608639), [How can I copy a file from one directory to another in c/c++](https://stackoverflow.com/q/7267295/608639), etc... – jww Jan 29 '18 at 00:25
  • @softengstu: I apologize if my comment was excessively rude. I had no idea this was your first encounter with Linux, but I'm not sure knowing that would have changed my comment much. I think it's reasonable to expect that a question about why an API fails to work should contain such basic information as the error returned and/or the specifics about the inputs to the API. – Michael Burr Jan 29 '18 at 21:25

2 Answers2

3

Your code will work in most cases. But you are ignoring some important things in which case it will break :

  • The obvious things like permissions, non-existing path, ...
  • Paths of 500 chars or more. Don't use static allocated memory for oldname and newname
  • Moving between filesystems is not possible with rename() so do it like this ( and include iostream )

    ifstream ifs(oldname, ios::in | ios::binary);
    ofstream ofs(newname, ios::out | ios::binary);
    ofs << ifs.rdbuf();
    remove(oldname);
    

    Before the remove() your total disk space will be a bit less.

    • This doesn't matter if your are moving between filesystems because only the free space on the filesystem with newname will shrink and this is free space you have because otherwise you wouldn't able to move the file here
    • If oldname and newname are on the same filesystem and you really care about this temporary loss then check whether you'll be using the same filesystem and use rename() after all.
Garo
  • 1,339
  • 12
  • 21
  • Your suggested copy to other fs fails to preserve permissions that move should preserve. – eerorika Jan 29 '18 at 09:19
  • Good point ! atime, mtime, ctime, UID and GID are also not preserved. This can all be avoided (if needed) by using `fstat()` on the original file before reading the contents. And before writing one could use `mknod` using the metadata from memory and only start writing after the file is created. Your code will become really long though... – Garo Jan 29 '18 at 10:58
  • The in and out flags are redundant btw. – pooya13 Jun 03 '20 at 02:53
1

How to fix your program depends on the reason why the move (rename) failed.

The reason for the failure can be found using errno.


In this case, it was necessary to make sure that the source file exists.

For all things that need to be considered to robustly implement moving, I recommend studying an implementation of mv command.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • The error I got with perror is "No such file or directory". The directory I tried moving it to does exist and I set permissions to 'create and delete files' so I don't see why I'd get that error message. – softengstu Jan 28 '18 at 23:14
  • @softengstu How did you verify that the directory exists? – eerorika Jan 28 '18 at 23:22
  • I tried moving it to the Documents folder which I see in Home, but when I ran a shell script just now to double check it seems like it doesn't exist. I also created a directory and then tried moving the file to the directory I just created and I get the same error message. – softengstu Jan 28 '18 at 23:31
  • If it seems like it doesn't exist, then that's clearly the reason why you cannot move a file there. – eerorika Jan 28 '18 at 23:34
  • Sorry, I made a mistake in the shell script (didn't include the full directory structure initially) - it does exist. – softengstu Jan 28 '18 at 23:43
  • Did you include the full directory structure in your program? – eerorika Jan 28 '18 at 23:43
  • Yes, I used the same full directory structure in my program as I used in the shell script that showed the file exists - for both the original and destination directories. – softengstu Jan 28 '18 at 23:49
  • By "full directory structure", do you mean absolute path? Or did you use a relative path? – eerorika Jan 28 '18 at 23:49
  • Yes, I used the absolute path – softengstu Jan 28 '18 at 23:52
  • I checked ls -l and the original file I was trying to move wasn't listed for some reason. I tested the program with a different file and it worked. Thanks for your help. – softengstu Jan 29 '18 at 00:01