今天为了对一个视频文件(.264格式)进行加密,使用了fopen和fread函数进行数据读取。但是问题出现了,我使用了以下代码
#define ENYMAXBUFSIZE 1024
FILE *stream = fopen( "test.264","r");
nRead=fread(ReadBuf,1,ENYMAXBUFSIZE,stream);
奇怪的事情是,调试时候发现只能读取258个数据。好像只读取了一行数据,下面就不会读取了。自己写了个txt数据文档,测试可以读完的。是什么原因呢?莫非.264格式有特殊东西?
以前也没遇到这状况啊。决定再好好看看fopen和fread函数,以下是MSDN上对两者的描述。
1) fopen函数
fopen supports Unicode file streams. To open a Unicode file, pass a ccs flag that specifies the desired encoding to fopen, as
follows.
fopen(&fp, "newfile.txt", "rw, ccs= encoding ");
Allowed values of encoding are UNICODE, UTF-8, and UTF-16LE.
the character string mode specifies the kind of access that is requested for the file, as follows.
"r" 、 "w" 、 "a" 、 "r+" 、 "w+" 、 "a+"
每个具体的意思可以参考 http://clanguage.h.baike.com/article-133342.html In addition to the earlier values, the following characters can be appended to mode to specify the translation mode for newline characters.
以下是关键:
t 模式
Open in text (translated) mode. In this mode, CTRL+Z is interpreted as an EOF character on input.
用文本(转换)模式打开文件。这种模式下, CTRL+Z被翻译成EOF字符进行输入。
在文本模式下,回车换行符的组合(\r\n)被转换成单个换行符输入,换行字符转换成回车换行符的组合输出。
当一个Unicode流的I/O功能函数在文本模式(默认)下操作,源或目标流被假定为是一个多字节字符序列。
因此,Unicode流输入函数将多字节字符转换为宽字符(好像被mbtowc功能调用,不是很懂!)。
同样的原因,Unicode流输出的功能将宽字符转换为多字节字符(如果调用的wctomb功能)。
备注:好多人对宽字节(widechar)和多字节(multibyte) 不能很好区分。宽字节就是不管英文还是汉字都是以2个字节(16位)存储(可以想象全英文的文本会增加一倍的存储),多字节就是英文1个字节汉字两个字节存储(8位,16位)。
2) fread函数The fread function reads up to count items of size bytes from the input stream and stores them in buffer.
If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters.
The replacement has no effect on the file pointer or the return value.
如果给定的流文件用文本模式打开,回车换行符组合会被单个换行符替换。这一替换并不会对文件指针或返回值有影响。
至此,我们应该明白为什么264文件我会读取失败了,因为我使用文本模式打开了264格式的文件。读文件时,会将回车换行符号CRLF(0x0D 0x0A)(\r\n)全部转换成单个的换行符0x0A,并且当遇到结束符CTRLZ(0x1A)时,就认为文件已经结束。(相应的,写文件时,会将所有的0x0A换成0x0D0x0A。).所以,若使用文本方式打开二进制文件时,就很容易出现文件读不完整,或內容不对的错误。
另附: