Thread: File and Device Size

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    6

    Question File and Device Size

    Hi,

    i need to get the Size of a file (e.g. ~/files/hallo.txt) and the size of a deivce (e.g. /dev/sdb).


    Is it possible to get both with the same functions?
    Do i need to use specific Funktions for block or character devices?



    Ps.:
    Later i need to reed the whole file/device.
    I need the file/device-size to show the progress.


    Thx for all answers,

    hd
    Last edited by haderach; 05-03-2010 at 03:21 AM.

  2. #2
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Note that the linked man page is for Linux:

    man 2 stat
    Last edited by kermit; 05-03-2010 at 04:19 AM.

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    and here's the same thing on Windows: _stat()
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    6
    I just copied the code out of the man-Page but:

    Code:
     
    printf("File size:                %lld bytes\n", (long long) sb.st_size);
    always prints: "0" if u have a block device.


    so i tried to lseek: but this alwas prinft "-1" if u have a block device?

    Code:
     
    fd = open(argv[1], 00);
    size = lseek(fd, 0, SEEK_END);
    close(fd);
    printf("SIZE %d \n", size);

    Am i doing something wrong?
    Last edited by haderach; 05-03-2010 at 07:14 AM.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    For streams, this works, for devices requiring a file handle, lseek() should work, but it won't work on terminals and printers, according to my help file.

    Code:
    /*
     fseek   Repositions the file pointer of a stream.
    
    
     Syntax:
       int fseek(FILE *stream, long offset, int whence);
    
     Prototype in:
     stdio.h
    
     Remarks:
    fseek sets the file pointer associated with stream to a new position
    that is offset bytes from the file location given by whence.
    
    For text mode streams, offset should be 0 or a value returned by
    ftell.
    
    whence must be one of the values 0, 1, or 2, which represent three
    symbolic constants (defined in stdio.h) as follows:
    
       whence         ³ File location
     ======================================
       SEEK_SET   (0) ³ File beginning
       SEEK_CUR   (1) ³ Current file pointer position
       SEEK_END   (2) ³ End-of-file
    
    fseek discards any character pushed back using ungetc.
    
    fseek is used with stream I/O. For file handle I/O, use lseek.
    
    After fseek, the next operation on an update file can be either input
    or output.
    
     Return Value:
    fseek returns 0 if the pointer is successfully moved. It returns a
    nonzero on failure.
    
    fseek can return a zero, indicating that the pointer has been moved
    successfully, when in fact it has not been. This is because DOS,
    which actually resets the pointer, does not verify the setting.
    
    fseek returns an error code only on an unopened file or device.
    
     Portability:
    fseek is available on all UNIX systems and is defined in ANSI C.
    
     See Also:
      fgetpos      fsetpos    lseek     setbuf
      fopen        ftell      rewind    tell
    
     Example:
     */
     #include <stdio.h>
    
     long filesize(FILE *stream);
    
     int main(void)
     {
        FILE *stream;
    
        stream = fopen("MYFILE.TXT", "w+");
        fprintf(stream, "This is a test");
        printf("Filesize of MYFILE.TXT is %ld bytes\n", filesize(stream));
        fclose(stream);
        return 0;
     }
    
     long filesize(FILE *stream)
     {
        long curpos, length;
    
        curpos = ftell(stream);
        fseek(stream, 0L, SEEK_END);
        length = ftell(stream);
        fseek(stream, curpos, SEEK_SET);
        return length;
     }

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    6
    I am using Linux and i use it on an usbstick (/dev/sdb)

    sudo ./fs /dev/sdb
    File type: block device
    I-node number: 3135617
    Mode: 60660 (octal)
    Link count: 1
    Ownership: UID=0 GID=6
    Preferred I/O block size: 4096 bytes
    File size: 0 bytes
    SIZE -1
    Blocks allocated: 0
    Last status change: Mon May 3 09:36:04 2010
    Last file access: Mon May 3 09:36:06 2010
    Last file modification: Mon May 3 09:36:04 2010
    cat fs.c
    Code:
    #include <sys/types.h>
    
    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define __USE_LARGEFILE64
    #define _LARGEFILE_SOURCE
    #define _LARGEFILE64_SOURCE
    #include <sys/stat.h>
    
            int
    main(int argc, char *argv[])
    {
        struct stat64 sb;
            int fd;
            unsigned long long size;
    
        if (argc != 2) {
            fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    
        if (stat64(argv[1], &sb) == -1) {
            perror("stat");
            exit(EXIT_FAILURE);
        }
    
        printf("File type:                ");
    
        switch (sb.st_mode & S_IFMT) {
            case S_IFBLK:  printf("block device\n");            break;
            case S_IFCHR:  printf("character device\n");        break;
            case S_IFDIR:  printf("directory\n");               break;
            case S_IFIFO:  printf("FIFO/pipe\n");               break;
            case S_IFLNK:  printf("symlink\n");                 break;
            case S_IFREG:  printf("regular file\n");            break;
            case S_IFSOCK: printf("socket\n");                  break;
            default:       printf("unknown?\n");                break;
        }
    
        printf("I-node number:            %ld\n", (long) sb.s
    
        printf("Mode:                     %lo (octal)\n",
                (unsigned long) sb.st_mode);
    
        printf("Link count:               %ld\n", (long) sb.s
        printf("Ownership:                UID=%ld   GID=%ld\n
                (long) sb.st_uid, (long) sb.st_gid);
    
        printf("Preferred I/O block size: %ld bytes\n",
                (long) sb.st_blksize);
        printf("File size:                %lld bytes\n",
                (long long) sb.st_size);
    
    
            fd = open64(argv[1], 00);
            size = lseek64(fd, 0, SEEK_END);
            close(fd);
            printf("SIZE %lld \n", (long long)size);
    
    
        printf("Blocks allocated:         %lld\n",
                (long long) sb.st_blocks);
    
        printf("Last status change:       %s", ctime(&sb.st_c
        printf("Last file access:         %s", ctime(&sb.st_a
        printf("Last file modification:   %s", ctime(&sb.st_m
    
        exit(EXIT_SUCCESS);
    }
    What am i doing wrong?
    Last edited by haderach; 05-03-2010 at 07:43 AM.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    My example is only for reading a file - similar to fseek, but using the file handle, instead of a stream mode.

    So I'm stumped.
    Last edited by Adak; 05-03-2010 at 08:13 AM.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    6
    Quote Originally Posted by Adak View Post
    Let me get the help file for lseek. I'm not a penguin-head.
    lseek(2)


    perhaps lseek isnt the answer to my problem but pv uses it :

    Code:
     77       if (S_ISBLK(sb.st_mode)) {
     78             /*
     79              * Get the size of block devices by opening
     80              * them and seeking to the end.
     81              */
     82             if (strcmp(opts->argv[i], "-") == 0) {
     83                 fd = open64("/dev/stdin", O_RDONLY);
     84             } else {
     85                 fd = open64(opts->argv[i], O_RDONLY);
     86             }
     87             if (fd >= 0) {
     88                 opts->size += lseek64(fd, 0, SEEK_END);
     89                 close(fd);
     90             }
     91         } else if (S_ISREG(sb.st_mode)) {
     92             opts->size += sb.st_size;
     93         } else {
     94             opts->size = 0;
     95         }
    Last edited by haderach; 05-03-2010 at 08:15 AM.

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    6

    Solved

    Solution:

    Code:
      1 #include <fcntl.h>
      2 #include <linux/fs.h>
      3 #include <stdio.h>
      4 
      5 
      6 main(int argc, char **argv)
      7 {
      8   int fd;
      9   unsigned long numblocks=0;
     10 
     11   fd = open(argv[1], O_RDONLY);
     12   ioctl(fd, BLKGETSIZE64, &numblocks);
     13   close(fd);
     14   printf("Number of bytes: %lu, this makes %.3f GB\n",
     15      numblocks,
     16      (double)numblocks / (1024 * 1024 * 1024));
     17 }

    Ps.: would be nice if someone can tell me why it is not working with lseek.


    THX2all

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The most definitive person to ask why it is not working is your machine.
    Code:
    numblocks = lseek(fd);
    if (numblocks == -1) {
        perror("Lseek didn't work because");
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 01-08-2009, 12:15 PM
  2. Invalid conversion from 'void*' to 'BYTE' help
    By bikr692002 in forum C++ Programming
    Replies: 9
    Last Post: 02-22-2006, 11:27 AM
  3. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM
  4. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM
  5. Replies: 1
    Last Post: 05-09-2002, 07:14 AM