Thread: Best way to see file's size

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    52

    Best way to see file's size

    I once made a script in C to receive a file name as argument in *argv and using fopen i would read each char until EOF. At the same time i would be calculating its size using sums.

    I cant remeber how much i would sum for each char i read, but that method was very ineficient and slow.

    Are there better examples of how to do it?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    ftell() is a standard function that will tell you the position from the beginning of a file. The fseek() function has an option to set the fileposition relative to the end of the file, so combining those two will tell you how long the file is without reading any of the content.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    May 2008
    Location
    Third rock from the Sun
    Posts
    1
    Another (not portable) solution: if you're on a *nix machine, the stat() function
    call can get some low-level information about the the file, including its size in bytes.

    Code:
    #include<stdio.h>
    #include<sys/stat.h>
    int main(int argc, char **argv){
        struct stat stbuf;
        if(stat(argv[1], &stbuf)==0)
            printf("-I- File size in bytes: %ld\n", stbuf.st_size);
        return 0;
    }
    If the file is a symbolic link st_size gives the length in bytes of the path name contained in the sym. link

    I think there's an equivalent function call in MSWin, but since this is not a
    standard C function YMMV, depending upon what you're using

    hope it helps

  4. #4
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by gradstudent View Post
    Another (not portable) solution: if you're on a *nix machine, the stat() function
    call can get some low-level information about the the file, including its size in bytes.

    Code:
    #include<stdio.h>
    #include<sys/stat.h>
    int main(int argc, char **argv){
        struct stat stbuf;
        if(stat(argv[1], &stbuf)==0)
            printf("-I- File size in bytes: %ld\n", stbuf.st_size);
        return 0;
    }
    If the file is a symbolic link st_size gives the length in bytes of the path name contained in the sym. link

    I think there's an equivalent function call in MSWin, but since this is not a
    standard C function YMMV, depending upon what you're using

    hope it helps
    There's also a stat() function on Windows.

  5. #5
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    I would think that passing the file pointer to a strlen like function would be pretty efficient and fast if you are tallying up all the pointers to char. Double check sizeof(char) for your system though.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    sizeof(char) is always one.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by slingerland3g View Post
    I would think that passing the file pointer to a strlen like function would be pretty efficient and fast if you are tallying up all the pointers to char. Double check sizeof(char) for your system though.
    1) that wouldn't work.
    2) sizeof(char) is always 1. Always.
    Last edited by King Mir; 06-11-2008 at 02:35 PM.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by slingerland3g View Post
    I would think that passing the file pointer to a strlen like function would be pretty efficient and fast if you are tallying up all the pointers to char.
    That would give you a warning in C and if you ignore it, most likely a crash to undefined behavior. In C++, it would never compile.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    Late response:

    Hmm not sure where you all were going with what I said. But tallying up all the chars within a file or string will give you it's size in bytes. The below should work, so maybe my wording of what I was trying to explain was off a bit.

    Code:
    :
    /*continue to read in file*/
    
     while (*filePointer++)
        {
          length++;
        }
    
      return length;
    :
    :

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    This works for a string and indeed, what most strlen implementations do, but it won't work for a file whose type is FILE*.
    Besides, it's also a very inefficient method for finding the size of a file.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User slingerland3g's Avatar
    Join Date
    Jan 2008
    Location
    Seattle
    Posts
    603
    "type is FILE*." Ok, ok.

    Thanks

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    FILE is a struct. How do you propose to use that as a boolean expression?
    That's impossible in C, so what you propose won't compile.
    Not to mention FILE is not an array, so trying to walk it using ++ would be undefined behavior.

    It would work on char*, char[], but not FILE*.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Not to mention FILE is not an array, so trying to walk it using ++ would be undefined behavior.
    Actually, I wouldn't want to guarantee that FILE is NOT an array - in many systems it would be. The problem with using ++ on a file-pointer, however, is that the struct FILE is not a known type in the application side, it's only known in the C-library side of the code (it's called an opaque pointer - it's a pointer to a struct, but you never "look inside it").

    Being an opaque pointer means that there's no way to use ++ on it, since the compiler is not able to figure out how much forward it should jump.

    And of course, even if we could "walk" the list of FILE structs, the code would definitely not tell you how big the file is - it would return some random value that is completely and utterly unrelated to the size of the file itself.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by matsp View Post
    ftell() is a standard function that will tell you the position from the beginning of a file. The fseek() function has an option to set the fileposition relative to the end of the file, so combining those two will tell you how long the file is without reading any of the content.
    That's the closest thing I know of to a portable solution except that..... it doesn't work portably. With some operating systems or disk drivers, the call of fseek() can fail without returning any error code, after which the return from ftell() is unpredictable.

    This method also relies on an assumption that a file size cannot exceed the maximum value that is representable in a long int, which is not true with some recent compilers or target platforms.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by grumpy View Post
    That's the closest thing I know of to a portable solution except that..... it doesn't work portably. With some operating systems or disk drivers, the call of fseek() can fail without returning any error code, after which the return from ftell() is unpredictable.
    I can't think of a reasonable solution to that one. Although I predict that this would also not work reliably for other fseek-related operations, so wouldn't that filesystem/disk driver be "black-flagged"?
    This method also relies on an assumption that a file size cannot exceed the maximum value that is representable in a long int, which is not true with some recent compilers or target platforms.
    In this case, the solution is to use the fgetpos/fsetpos functions, that take a "fpos_t" type - this type should be correctly sized for any file-size that the OS supports if the C library implementation is done correctly. Unfortunately, fgetpos/fsetpos are not standard functions, but exist in both Linux and MS runtime libraries at the very least.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Code review
    By Elysia in forum C++ Programming
    Replies: 71
    Last Post: 05-13-2008, 09:42 PM
  2. Replies: 16
    Last Post: 11-23-2007, 01:48 PM
  3. char problem
    By eXistenZ in forum Windows Programming
    Replies: 36
    Last Post: 02-21-2005, 06:32 AM
  4. Replies: 11
    Last Post: 03-25-2003, 05:13 PM
  5. Size of exe files
    By Korn1699 in forum C++ Programming
    Replies: 6
    Last Post: 03-25-2002, 09:46 PM