场景
         fopen函数还是fstream类对象中的open函数在打开文件时,没有指定任何的打开方式,保存的视频流无法播放。使用Elecard StreamEye Tools查看视频流的时候,MB窗口显示:incorrect block info。使用VLC播放,花屏。


原因
         在Unix或者Linux系统中,没有文本方式和二进制方式。Unix文本文件的换行符只有一个字节LF(0x0A)为。在C语言中,也是以LF即'\n'为换行符。 在DOS和Windows系统中使用CRLF(0x0D
0x0A)即\r\n双字节作为文本文件换行符。在以文本方式下,在读文件时,会将换行符号CRLF(0x0D0x0A)全部转换成单个的0x0A,并且当遇到结束符CTRLZ(0x1A)时,就认为文件已经结束。相应的,写文件时,会将所有的0x0A换成0x0D0x0A。因此如果以文本方式读写文件,会造成文件读取不完整,写文件内容添加多余的0x0D字符。


提供一份将视频中的0x0D0x0A中的多余字节0x0D删除的代码段


#include <iostream>
#include <fstream>
#include <string>

int main()
{
 std::ifstream ifstreamHandle;
 ifstreamHandle.open("F:/video.h264", std::ifstream::in | std::ifstream::binary);    
 ifstreamHandle.seekg(0, std::ios::end);  
 int nFileLen = ifstreamHandle.tellg();          
 ifstreamHandle.seekg(0, std::ios::beg);   
 char* pszReadBuffer = new char[nFileLen];   
 memset(pszReadBuffer, 0x00, nFileLen);
 ifstreamHandle.read(pszReadBuffer, nFileLen);
 ifstreamHandle.close();

 std::ofstream ofstreamHanle;
 ofstreamHanle.open("F:/videoOutput.h264", std::ofstream::out | std::ofstream::binary);
 for (int i = 1; i < nFileLen; i++)
 {
  if ((0x0d == pszReadBuffer[i - 1]) && (0x0a == pszReadBuffer[i]))
  {
   //还有多余的0x0d字符,不写文件
  }
  else
  {
   ofstreamHanle << pszReadBuffer[i-1];
  }
 }
 //将最后一个字节写文件
 ofstreamHanle << pszReadBuffer[nFileLen - 1];
 ofstreamHanle.close();

 delete pszReadBuffer;
}