cfilestreamrenamedirent.h

Is it possible to rename a file in C using directory streams?


I'm new to C. I've coded this program that allows me to batch rename files in a same directory (mostly shows). It's currently using the Rename function from stdio while using the dirent struct to find the "old name". However, that means having to add the "new name" and the "old name" to a "path string" so that Rename can find the files. I was hoping there was a way to alter file names directly using dirent.

I tried changing dp->d_name to the "new name" but that did not change the file names.

This is not my full working program but code I've been using to try to test other methods of renaming.

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(){

  DIR *dirp;
  struct dirent *dp;
  char dir[500];
  char pathOne[500] = "Testing.txt";
  int i;


  printf("\nPlease enter the target directory :\n");
  scanf("%[^\n]s",dir);

  dirp = opendir(dir);

  printf(dirp ? "Directory Connection Successful\n\n" : "Directory Connection Failed\n\n");
  printf("%s\n", pathOne);

  while(dp = readdir(dirp)){
    if((dp->d_name[0])!='.'){
      for(i = 0; dp->d_name[i] = pathOne[i]; i++);
      printf("%s\n", dp->d_name);
    }
  }


  return 0;
}
Please enter the target directory :
H:\Documents\TestFolder
Directory Connection Successful

Testing.txt
Testing.txt
Testing.txt
Testing.txt

Press any key to continue . . .

This is what I get in the console but the file names in the explorer were not changed.


Solution

  • struct dirent is to represent the directory structure in the program which you will read using readdir, modifying the contents of it, will not effect the actual structure of directory.

    The structure is meant to hold the certain information of particular file in the directory thus it has no link to the actual file.

       struct dirent {
           ino_t          d_ino;       /* Inode number */
           off_t          d_off;       /* Not an offset; see below */
           unsigned short d_reclen;    /* Length of this record */
           unsigned char  d_type;      /* Type of file; not supported
                                          by all filesystem types */
           char           d_name[256]; /* Null-terminated filename */
       };
    

    You can use rename system call to rename the actual file.

    Example:

      while(dp = readdir(dirp)){
        if((dp->d_name[0])!='.'){
          char oldPath[1024], newPath[1024];
    
          sprintf(oldPath, "%s/%s",dir, dp->d_name);
          sprintf(newPath, "%s/%s",dir, pathOne);
          if (rename(oldPath, newPath) < 0)
            printf("rename error path=%s", oldPath);
        }
      }