Jack S
Jack S

Reputation: 43

Displaying size of a file [C]

I'm making a simple sockets program to send a text file or a picture file over to another socket connected to a port. However, I want to also send the size of the file over to the client socket so that it knows how many bytes to receive.

I also want to implement something where I can send a certain number of bytes instead of the file itself. For example, if a file I wanted to send was 14,003 bytes and I felt like sending 400 bytes, then only 400 bytes would be sent.

I am implementing something like this:

 #include <stdio.h>

 int main(int argc, char* argv[]) {
     FILE *fp;
     char* file = "text.txt";
     int offset = 40;
     int sendSize = 5;
     int fileSize = 0;

     if ((fp = fopen(file, "r")) == NULL) {
         printf("Error: Cannot open the file!\n");
         return 1;
     } else {
         /* Seek from offset into the file */
         //fseek(fp, 0L, SEEK_END);
         fseek(fp, offset, sendSize + offset); // seek to sendSize
         fileSize = ftell(fp); // get current file pointer
         //fseek(fp, 0, SEEK_SET); // seek back to beginning of file
     }

     printf("The size is: %d", fileSize);
 }

offset is pretty much going to go 40 bytes into the file and then send whatever sendSize bytes over to the other program.

I keep getting an output of 0 instead of 5. Any reason behind this?

Upvotes: 0

Views: 620

Answers (4)

Andrew Henle
Andrew Henle

Reputation: 1

You may be opening the file in text mode as Windows can open a file in text mode even without the "t" option.

And you can't use ftell() to get the size of a file opened in text mode. Per 7.21.9.4 The ftell function of the C Standard:

For a text stream, its file position indicator contains unspecified information, usable by the fseek function for returning the file position indicator for the stream to its position at the time of the ftell call; the difference between two such return values is not necessarily a meaningful measure of the number of characters written or read.

Even if it does return the "size" of the file, the translation to "text" may changed the actual number of bytes read.

It's also not portable or standard-conforming to use fseek() to find the end of a binary file. Per 7.21.9.2 The fseek function:

A binary stream need not meaningfully support fseek calls with a whence value of SEEK_END.

Upvotes: 1

Malcolm McLean
Malcolm McLean

Reputation: 6404

The fseek() to the end, then ftell() method is a reasonably portable way of getting the size of a file, but not guaranteed to be correct. It won't transparently handle newline / carriage return conversions, and as a result, the standard doesn't actually guarantee that the return from ftell() is useful for any purpose other than seeking to the same position.

The only portable way is to read the file until data runs out and keep a count of bytes. Or stat() the file using the (non-ANSI) Unix standard function.

Upvotes: 1

Ren&#233; W.
Ren&#233; W.

Reputation: 148

I think your Seek does not work due to the 3rd parameter: try to seek with
(fp, offset, SEEK_SET);

as he will try to use the number sendSize+Offset as the "origin" constant, it will be compared to the 3 constant values as below (it is 0, 1 or 2) and as nothing compares it seem to return 0 all time.

http://www.cplusplus.com/reference/cstdio/fseek/

Parameters

stream, offset, origin

Position used as reference for the offset. It is specified by one of the following constants defined in exclusively to be used as arguments for this function:

Constant Reference position
SEEK_SET Beginning of file
SEEK_CUR Current position of the file pointer
SEEK_END End of file

Upvotes: -1

Ajish Kb
Ajish Kb

Reputation: 480

You can try this.

#include <stdio.h>

int main(int argc, char* argv[]) {
    FILE *fp;
    char* file = "text.txt";
    int offset = 40;
    int sendSize = 5;
    int fileSize = 0;

    if ((fp = fopen(file, "r")) == NULL) {
        printf("Error: Cannot open the file!\n");
        return 1;
    } else {
        fseek(fp, 0L, SEEK_END);
        fileSize = ftell(fp);
    }

    printf("The size is: %d", fileSize);
}

Upvotes: 1

Related Questions