3

I need to find the size of a file or a directory whatever given in the commandline using stat(). It works fine for the files (both relative and absolute paths) but when I give a directory, it always returns the size as 512 or 1024.

If I print the files in the directory it goes as follows :

 Name : .
 Name : ..
 Name : new
 Name : new.c

but only the new and new.c files are actually in there. For this, the size is returned as 512 even if I place more files in the directory. Here s my code fragment:

if (stat(request.data,&st)>=0){
        request.msgType = (short)0xfe21;
        printf("\n Size : %ld\n",st.st_size);
        sprintf(reply.data,"%ld",st.st_size);
        reply.dataLen = strlen(reply.data);
    }
    else{
        perror("\n Stat()");
    }
}

Where did I go wrong???

here is my request, reply structure:

 struct message{
        unsigned short msgType;
        unsigned int offset;
        unsigned int serverDelay;
        unsigned int dataLen;
        char data[100];
    };
struct message request,reply;

I run it in gcc compiler in unix os.

Sree
  • 33
  • 1
  • 4
  • what os/compiler? also, what is this request/reply structure? – chacham15 Sep 02 '12 at 22:33
  • 1
    If you place enough files in the directory, it will grow bigger than 512 or 1024 bytes. For example, if you add 120 file names where each name is 10 or more characters, you can reasonably expect a size larger than 1024 bytes. – Jonathan Leffler Sep 02 '12 at 22:50

3 Answers3

9

stat() on a directory doesn't return the sum of the file sizes in it. The size field represents how much space it taken by the directory entry instead, and it varies depending on a few factors. If you want to know how much space is taken by all files below a specific directory, then you have to recurse down the tree, adding up the space taken by all files. This is how tools like du work.

John Szakmeister
  • 44,691
  • 9
  • 89
  • 79
  • Oh ok. Then I guess I need to check whether its a directory, and if it is, thhen I need to do opendir() and readdir() each file and stat() it seperately. I dont know how to use du in a c program though. Its a unix command to find the disk usage of the current directory right..??? – Sree Sep 02 '12 at 23:26
  • 1
    Yes, if it's a directory, you need to do an `opendir()`, `readdir()`, and `stat()` each file in it. I don't necessarily recommend using `du` from within your C program... it was just an example of a program that takes this approach. – John Szakmeister Sep 03 '12 at 09:52
1

Yes. opendir() + loop on readdir()/stat() will give you the file/directory sizes which you can sum to get a total. If you have sub-directories you will also have to loop on those and the files within them.

To use du you could use the system() function. This only returns a result code to the calling program so you could save the results to a file and then read the file. The code would be something like,

system("du -sb dirname > du_res_file");

Then you can read the file du_res_file (assuming it has been created successfully) to get your answer. This would give the size of the directory + sub-directories + files in one go.

Alec Danyshchuk
  • 307
  • 2
  • 12
0

Im sorry, I missed it the first time, stat only gives the size of files, not directories:

These functions return information about a file. No permissions are required on the file itself, but-in the case of stat() and lstat() - execute (search) permission is required on all of the directories in path that lead to the file.

The st_size field gives the size of the file (if it is a regular file or a symbolic link) in bytes. The size of a symbolic link is the length of the pathname it contains, without a terminating null byte.

look at the man page on fstat/stat

Community
  • 1
  • 1
chacham15
  • 13,719
  • 26
  • 104
  • 207
  • But it (typically) *does* give the size of a directory. A Unix directory is a special file. For example, my home directory has a size of 4096 bytes. (That's not directly related to the sizes of any files that it "contains".) – Keith Thompson Sep 03 '12 at 00:35