乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      關(guān)于fread的問答

       haodafeng_org 2011-01-28
      從一個(gè)文件中把數(shù)據(jù)復(fù)制到另外一個(gè)文件中,我的代碼如下:
      while (i<38016)//文件大小為38016字節(jié),i(unsigned int),temp(char)
      {
       fread(&temp,1,1,fyuv);
       fwrite(&temp,1,1,fyuv1);
       i++;
      }
      結(jié)果文件有38k,其中前面大概10k是正確的(與源文件進(jìn)行二進(jìn)制代碼比對(duì)),后面的約28k就重復(fù)前面10k的最后一個(gè)字節(jié),也就是后面28k所有字節(jié)完全一樣。
      若把代碼換成:
      do
      {
       i=fread(&temp,1,1,fyuv);
       fwrite(&temp,i,1,fyuv1);
      }while(i>0);
      則得到的結(jié)果文件大概只有10k,且這10k與源文件的前10k一樣(比對(duì)二進(jìn)制代碼),但是后28k就沒有了。
      請(qǐng)問我該怎么做才是正確的呢?
      錯(cuò)誤原因:
      你用文本方式打開了二進(jìn)制文件

      文本方式讀取二進(jìn)制數(shù)據(jù), 可能在文件結(jié)束之前將某段數(shù)據(jù)判定為文件末尾EOF, 所以結(jié)束讀取( 舉個(gè)例子, 比如遇到 0x00 0x00 0xff 0xff, 則文本方式方式的文件流, 認(rèn)為已經(jīng)到文件末尾, 不能讀取)

      你這個(gè)38016的文件, 大概在10k左右有段數(shù)據(jù)和文件結(jié)束標(biāo)志格式相同, 文本方式讀取到10k左右就認(rèn)為文件結(jié)束了( 真正的文本文件, 結(jié)束標(biāo)志可能在磁盤簇的剩余空間中 )

      所以第一種方式:
      固 定讀取38016次, 每次往新文件中寫一個(gè)字節(jié); 前10k次能讀取到內(nèi)容, fread返回值是1, 這樣寫過去的一字節(jié)就是讀取的字節(jié); 后28k因?yàn)樽x取失敗, fread返回值為0, 這樣temp的內(nèi)容就不會(huì)被改寫, 仍然是最后一次成功讀取的值, 但因?yàn)槭菍懘螖?shù)固定, 所以后28k就重復(fù)寫過去;
      后一種方式:
      根據(jù)fread的返回值來判定文件結(jié)束, 這是正確的方法; 所以讀取到10k后, 返回值為0, 表示無效, 文件結(jié)束, 所以只復(fù)制了10k內(nèi)容

      CFile只支持二進(jìn)讀寫, 所以你的結(jié)果是正確的( CFile用CFile::typeText格式會(huì)報(bào)錯(cuò); CStdioFile才能文本讀寫)
      用fopen返回的FILE, 如果讀取的時(shí)候沒有加b( 比如"r"), 則默認(rèn)的是文本格式; 所以請(qǐng)用"rb"來讀取二進(jìn)制文件, 用"wb"寫二進(jìn)制文件; 當(dāng)然如果只是復(fù)制文件的話, 純二進(jìn)制讀寫沒有問題

      下面是樓主要的效果, 是一個(gè)字節(jié)讀寫的
      #include <stdio.h>
      int main()
      {
      FILE *pFileS = fopen( "s.rar", "rb" );
      if( ! pFileS )
      return 1;
      FILE *pFileD = fopen( "d.rar", "wb+" );

      unsigned char bTemp;
      while( fread( &bTemp, sizeof(unsigned char), 1, pFileS) )
      fwrite( &bTemp, sizeof(unsigned char), 1, pFileD );

      fclose( pFileS ), fclose( pFileD );
      return 0;
      }
      其實(shí)一個(gè)字節(jié)讀寫的話, 用fgetc和fputc就可以了, 當(dāng)然還是得以二進(jìn)制方式打開

      另外單字節(jié)讀寫速度太慢; 系統(tǒng)中復(fù)制文件都是整塊讀寫的, 設(shè)置緩沖大小
      比如
      #include <stdio.h>
      int main()
      {
      FILE *pFileS = fopen( "s.rar", "rb" );
      if( ! pFileS )
      return 1;
      FILE *pFileD = fopen( "d.rar", "wb" );

      unsigned char buffer[ 4 * 1024 ];
      int nRead;
      while( nRead = fread( buffer, sizeof(unsigned char), sizeof(buffer), pFileS ) )
      fwrite( buffer, sizeof(unsigned char), nRead, pFileD );

      fclose( pFileS ), fclose( pFileD );
      return 0;
      }

      另外, fread單次讀取的總字節(jié)數(shù)有限制, 也就是說緩沖有上限; 只能通過提高次數(shù)來讀取大文件; 在這方面, 用API如ReadFile或者調(diào)用了這些API的封裝類就好得多; 當(dāng)然, 次數(shù)多對(duì)電腦來說不是問題呵呵

      附:
      至于文本方式不能完全讀取, 而二進(jìn)制方式能的原因-
      文 本方式讀取文件, 最主要的用處是一次讀取一整句( 以換行符'\n', 即二進(jìn)制的換行標(biāo)志"\r\n"結(jié)束 ), 方便用于特殊用處ReadString、fscanf(...,"%s",...)之類, 每次讀取的內(nèi)容長(zhǎng)度是不定的; 而二進(jìn)制讀取方式Read、fread等, 都是讀取固定長(zhǎng)度
      所以文本方式讀取對(duì)EOF的判定, 是一個(gè)文件尾結(jié)束標(biāo)志, 如果是文本文件, 則這個(gè)文件尾肯定不會(huì)出現(xiàn)在文件內(nèi)容中( 因?yàn)槭遣豢纱蛴∽址麡?gòu)成的結(jié)束標(biāo)志, 人可讀的文本文件不會(huì)包括它 ), 這樣以結(jié)束標(biāo)志為文件尾則是可以的; 二進(jìn)制文件內(nèi)容可以是任意字節(jié), 如果把它當(dāng)文本文件來讀, 以文件尾為結(jié)束, 當(dāng)然可能出現(xiàn)把文件內(nèi)容判定為文件尾的情況;
      二進(jìn)制讀取方式 由于每次讀取固定字節(jié), 所以只需要用總文件長(zhǎng)度( 這個(gè)數(shù)值是系統(tǒng)管理的數(shù)值, 不是計(jì)算得出來的 )減去每次讀取的長(zhǎng)度( 或根據(jù)Seek的位置計(jì)算長(zhǎng)度 ), 就可以知道是否到文件尾, 不需要定義結(jié)束標(biāo)志; 所以用二進(jìn)制方式打開任何文件都是合理的 

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多