0

我正在制作一个简单的套接字程序,以将文本文件或图片文件发送到连接到端口的另一个套接字。但是,我还想将文件的大小发送到客户端套接字,以便它知道要接收多少字节。

我还想实现一些可以发送一定数量的字节而不是文件本身的东西。例如,如果我要发送的文件是 14,003 字节,而我想发送 400 字节,那么只会发送 400 字节。

我正在实施这样的事情:

 #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几乎会将 40 个字节放入文件中,然后将任何sendSize字节发送到其他程序。

我不断得到输出0而不是5。这背后有什么原因吗?

4

4 回答 4

1

你可以试试这个。

#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);
}
于 2016-10-14T07:21:45.900 回答
1

您可能会以文本模式打开文件,因为即使没有选项, Windows 也可以以文本模式打开文件"t"

而且您不能ftell()用来获取以文本模式打开的文件的大小。根据7.21.9.4 C 标准的ftell功能

对于文本流,其文件位置指示符包含未指定的信息,fseek函数可用于将流的文件位置指示符返回到ftell调用时的位置; 两个这样的返回值之间的差异不一定是衡量写入或读取字符数的有意义的指标

即使它确实返回了文件的“大小”,转换为“文本”也可能会改变实际读取的字节数。

它也不是可移植的或不符合标准的fseek()用于查找二进制文件的结尾。根据7.21.9.2 fseek 功能

二进制流不需要有意义地支持值为 的fseek调用 。whenceSEEK_END

于 2016-10-14T20:21:01.090 回答
1

fseek() 到最后,然后 ftell() 方法是获取文件大小的合理可移植方法,但不能保证正确。它不会透明地处理换行符/回车符转换,因此,该标准实际上并不能保证 ftell() 的返回值可用于除寻找相同位置之外的任何目的。

唯一可移植的方法是读取文件直到数据用完并保持字节数。或 stat() 使用(非 ANSI)Unix 标准函数的文件。

于 2016-10-14T07:50:52.287 回答
-1

我认为由于第三个参数,您的 Seek 不起作用:尝试使用
(fp, offset, SEEK_SET);

因为他会尝试使用数字 sendSize+Offset 作为“原点”常量,所以它将与下面的 3 个常量值(它是 0、1 或 2)进行比较,并且没有任何比较,它似乎一直返回 0。

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

参数

stream, offset, origin

用作偏移量参考的位置。它由以下定义的常量之一指定,专门用作此函数的参数:

常量 参考位置
SEEK_SET 文件
开头 SEEK_CUR 文件指针的当前位置 SEEK_END 文件
结尾

于 2016-10-14T07:35:42.337 回答