我正在制作一个简单的套接字程序,将文本文件或图片文件发送到连接到端口的另一个套接字。但是,我还想将文件的大小发送到客户端套接字,以便它知道要接收多少字节。
我还想实现一些东西,我可以发送一定数量的字节而不是文件本身。例如,如果我想发送一个14003字节的文件,而我想发送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
的输出。这背后有什么原因吗?
你可以试试这个
#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);
}
fseek()到最后,然后ftell()方法是一种合理的可移植的获取文件大小的方法,但不能保证正确。它不会透明地处理换行符/回车符的转换,因此,标准实际上并不能保证ftell()的返回值除了寻找相同的位置之外对任何目的都有用。
唯一可移植的方法是读取文件直到数据耗尽并保持字节数。或者使用(非ansi) Unix标准函数stat()文件。
您可能以文本模式打开文件,因为Windows即使没有"t"
选项也可以以文本模式打开文件。
并且您不能使用ftell()
来获取在文本模式下打开的文件的大小。C标准的ftell
函数:
对于文本流,其文件位置指示器包含未指定的信息,可由
fseek
函数返回该文件位置指示器用于将水流移至其当时的位置ftell
调用;两个这样的返回值之差价值不一定是有意义的数量的衡量标准.
即使它返回文件的"size",转换为"text"也可能改变实际读取的字节数。
使用fseek()
来查找二进制文件的末尾也是不可移植的或不符合标准的。Per 7.21.9.2fseek
函数:
二进制流不需要有意义地支持
fseek
调用SEEK_END
的whence
值。
我认为你的Seek不工作,由于第三个参数:尝试查找(fp, offset, SEEK_SET);
因为他将尝试使用数字sendSize+Offset作为"origin"常量,它将与下面的3个常量值进行比较(它是0,1或2),并且由于没有比较,它似乎始终返回0。
http://www.cplusplus.com/reference/cstdio/fseek/参数用作偏移量参考的位置。它由以下常量之一指定,该常量定义为专用于此函数的参数:
常量参考位置
SEEK_SET文件开头
SEEK_CUR文件指针的当前位置
SEEK_END文件结束