2

I'm not sure if C can do this, but I'm hoping that I can make a program that will look into a directory, and print out all of the contents of the directory along with the file size of each file. As in I wanted it to look like this (possibly):

filename.txt -- 300 bytes

filename2.txt -- 400 bytes

filename3.txt -- 500 bytes

And so on.

So far, I created a program that can open a file, and it will print the bytes, but it does not read the entire directory, and I have to be specific with which file I want to read.. (which is not what I want).

Here is what I have so far:

#include <stdio.h>

int main(){
    FILE *fp; // file pointer
    long fileSize;
    int size;

    // opens specified file and reads
    fp = fopen( "importantcommands.txt", "rw" );
    
    if( fp == NULL ){
        printf( "Opening file error\n" );
        return 0;
    }

    // uses fileLength function and prints here
    size = fileLength(fp);
    printf( "\n Size of file: %d bytes", size );

    fclose(fp);

    return 0;
}

int fileLength( FILE *f ){
    int pos;
    int end;

    // seeks the beginning of the file to the end and counts
    // it and returns into variable end
    pos = ftell(f);
    fseek (f, 0, SEEK_END);
    end = ftell(f);
    fseek (f, pos, SEEK_SET);

    return end;
}

Please help.

Community
  • 1
  • 1
chakolatemilk
  • 833
  • 9
  • 21
  • 31

6 Answers6

5

C can certainly do it - the ls(1) command can, for example, and it's written in C.

To iterate over a directory, you can use the opendir(3) and readdir(3) functions. It's probably easier to just let the shell do it for you, though.

As far as getting the filename, you can just take it as a command line parameter by defining main as:

int main(int argc, char **argv)

Command line parameters will begin at argv[1].

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
3

See opendir() / fdopendir() and readdir() if you are using linux in dirent.h man page

Simple example from a : SO Post

DIR *dir;  
struct dirent *ent;
if ((dir = opendir ("c:\\src\\")) != NULL) {
  /* print all the files and directories within directory */
  while ((ent = readdir (dir)) != NULL) {
     printf ("%s\n", ent->d_name);
  }
  closedir (dir);
} 
else {
  /* could not open directory */
  perror ("Could not open directory");
  return EXIT_FAILURE;
}   

Also You can use the fstat() system call which can fill in the struct stat for any file you want. From that stat you can access that file's size.
Please use the man pages to help you out. (Almost) Everything related to Linux is insanely well documented.

Community
  • 1
  • 1
Deepankar Bajpeyi
  • 5,661
  • 11
  • 44
  • 64
  • Okay so this one worked out really great. I was able to list all the contents of the directory.. Now is there a way I can find the file size of each file that was listed and print it after the name? I've done this (it only listed the size of the first file): `int main(){ DIR *dir; FILE *fp; struct dirent *ent; int size; if((dir = opendir("c:/")) != NULL){ while(fp = fopen("ex.txt", "rw")){ size = fileLength(fp); } while((ent = readdir (dir)) != NULL){ printf( "%s, size: %d\n", ent->d_name, size ); } closedir( dir ); } else{ perror( "" ); return -1; } }` – chakolatemilk Jan 28 '13 at 19:44
  • 1
    `fstat` stats a file which is already open (it takes a file descriptor); to stat a file that hasn't already been opened, you should use [`stat(2)`](http://linux.die.net/man/2/stat) instead. – Adam Rosenfield Jan 30 '13 at 23:54
2

To read a list of files in a directory look at opendir, readdir, closedir for Linux

use stat to get the length of the file.

These are of Linux

For winodws see http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365200%28v=vs.85%29.asp and the link http://blog.kowalczyk.info/article/8f/Get-file-size-under-windows.html will show you how to do this.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
0

To get the list of files in a directory look for "libc opendir". To get the size of a file without opening it you can use fstat.

Emanuele Paolini
  • 9,912
  • 3
  • 38
  • 64
0

This seems strangely similar to another question I saw recently. Anyway, here's my strangely similar answer (for Linux, not sure how it'll fare on Windows 7):

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>

int main(int argc, char *argv[]) {
    struct stat file_stats;
    DIR *dirp;
    struct dirent* dent;

    dirp=opendir("."); // specify directory here: "." is the "current directory"
    do {
        dent = readdir(dirp);
        if (dent)
        {
            printf("%s  --  ", dent->d_name);
            if (!stat(dent->d_name, &file_stats))
            {
                printf("%u bytes\n", (unsigned int)file_stats.st_size);
            }
            else
            {
                printf("(stat() failed for this file)\n");
            }
        }
    } while (dent);
    closedir(dirp);
}
phonetagger
  • 7,701
  • 3
  • 31
  • 55
0

There are little things need to be taken care for the given examples (under Linux or other UNIX).

  1. You properly only want to print out the file name and size of a regular file only. Use S_ISREG() to test the st_mode field
  2. If you want to recursively print out all files under sub directories also, you then need to use S_ISDIR() to test for direcotry and be carefull of special directory '.' and '..'.
qunying
  • 428
  • 3
  • 4