user-0 提问: 为什么在C语言中用文件操作将一个视频文件分割后再合成 结果不能播放了

回复:
user: user-1
content: //合成文件使用比如 WinExec("cmd /c copy /b 文件1+文件2+文件3 文件123",SW_HIDE);

user: user-1
content: 仅供参考：#include <sys\stat.h> #include <io.h> #include <fcntl.h> #include <share.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <string.h> #define MAX_CLU_BYTES 65536 FILE *fo; int fh; __int64 offs,offs1; __int64 rvi64; int rv,wrv; unsigned char buf[MAX_CLU_BYTES]; char ofn[_MAX_PATH]; char offstr[80]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; char fullpath[_MAX_PATH]; void strcpybutcomma(char *t,char *s) {     char c;      while (1) {         c = *s++;         if (','!=c) *t++ = c;         if (0==c) break;     } } int main(int argc,char **argv) {     if (argc<3) {         printf("Copy File Tail.\n");         printf("Usage:\n");         printf("    cft filename.ext {Offset_Begin|-Offset_End|Offset_Begin-Offset_End}\n");         printf("Copy filename.ext {OB|-OE|OB-OE} to {OB|~OE|OB-OE}-filename.ext\n");         printf("Note: Byte at OE is NOT included.\n");         printf("Example:\n");         printf("    cft abc.rar 12345\n");         printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n");         printf("    cft abc.rar -12345\n");         printf("Copy abc.rar offset -12345-end to ~12345-abc.rar\n");         printf("    cft abc.rar 123-12345\n");         printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n");         printf("    cft abc.rar 0xAB-0xCD\n");         printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n");         return 1;     }     strcpybutcomma(offstr,argv[2]);     rv=sscanf(offstr,"%I64i-%I64i",&offs,&offs1);     if (rv==0) {         printf("offset %s is not number\n",argv[2]);         return 2;     }     if (NULL==_fullpath(fullpath,argv[1],_MAX_PATH)) {         printf("Can not get fullpath of %s\n",argv[1]);         return 10;     }     fh=_sopen(fullpath,_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYNO);     if (fh==-1) {         printf("_sopen %s errno=%d %s\n",fullpath,errno,strerror(errno));         return 3;     }     if (rv==1) {         offs1=_filelengthi64(fh);         if (offs1==-1i64) {             printf("%I64d=_filelengthi64 errno=%d %s\n",offs1,errno,strerror(errno));             _close(fh);             return 4;         }         if (offs<0i64) {             offs=offs1+offs;             if (offs<0i64) offs=0i64;         }     } else {//rv==2         if (offs>offs1) {             printf("%s offset_begin %I64d > %I64d offset_end error\n",argv[2],offs,offs1);             _close(fh);             return 5;         }     }     rvi64=_lseeki64(fh,offs,SEEK_SET);     if (rvi64!=offs) {         printf("%I64d=_lseeki64 %I64d errno=%d %s\n",rvi64,offs,errno,strerror(errno));         _close(fh);         return 6;     }     _splitpath(fullpath,drive,dir,fname,ext);     if (offstr[0]=='-') offstr[0]='~';     sprintf(ofn,"%s%s%s-%s%s",drive,dir,offstr,fname,ext);     fo=fopen(ofn,"wb");     if (fo==NULL) {         printf("fopen %s errno=%d %s\n",ofn,errno,strerror(errno));         _close(fh);         return 7;     }     cprintf("\n%I64d\r",offs);     while (1) {         rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES));         if (rv==0) break;//         if (rv<0) {             printf("_read %s offset %I64d errno=%d %s\n",fullpath,offs,errno,strerror(errno));             fclose(fo);             _close(fh);             return 8;         }         wrv=fwrite(buf,1,rv,fo);         if (wrv!=rv) {             printf("fwrite %s errno=%d %s\n",ofn,errno,strerror(errno));             fclose(fo);             _close(fh);             return 9;         } else {             offs+=rv;             cprintf("%I64d\r",offs);             if (offs>=offs1) break;//         }     }     fclose(fo);     _close(fh);     printf("Copy %s offset %s to %s OK.\n",fullpath,argv[2],ofn);     return 0; }

user: user-1
content: 不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

user: user-2
content: 肯定是读文件和写文件生成的文件内容不一致引起的啊。 先比较一下2个文件，然后再单步一下。

user: user-3
content: while(!feof(fp)) { ch=fgetc(fp); fputc(ch,fp1); } 貌似有问题，试试： ch=fgetc(fp); while(!feof(fp)) { fputc(ch,fp1); ch=fgetc(fp); }

user: user-0

user: user-0
content: 在文件合成的接口处多了一个FF

user: user-0
content: 我用过CRC校验的一个小工具看过，生成的校验码不一样，我要怎么才能实现最终的播放呢，有没有什么方法

user: user-1
content: 视频文件不是简单的流，还带格式信息。

user: user-3
content: 原文件与分割、合成后的文件比较过完全一样吗？可以计算MD5，也可以cmd命令行fc命令来比较。