2011-07-05 72 views
2

我編寫了一個程序,用於讀取二進制文件,對其內容執行一些處理並將結果寫入其他文件。在Linux中它可以很好地工作,但在Windows中不起作用;輸出文件始終1KB ...Windows中的二進制輸出

這是程序的簡化版本:

#include <stdio.h> 

void copyFile(char* source, char* dest); 

int main (int argc, char* argv[]) 
{ 
    if (argc != 3) 
     printf ("usage: %s <source> <destination>", argv[0]); 
    else 
    { 
     copyFile(argv[1], argv[2]); 
    } 
} 


void encryptFile(char* source, char* destination) 
{ 
    FILE *sourceFile; 
    FILE *destinationFile; 

    int fileSize; 

    sourceFile = fopen(source, "r"); 
    destinationFile = fopen(destination, "w"); 

    if (sourceFile == 0) 
    { 
     printf ("Could not open source file\n"); 
     return; 
    } 

    if (destinationFile == 0) 
    { 
     printf ("Could not open destination file\n"); 
     return; 
    } 

    // Get file size 
    fseek(sourceFile, 0, SEEK_END); // Seek to the end of the file 
    if (ftell(sourceFile) < 4) 
     return; // Return if the file is less than 4 bytes 
    fseek(sourceFile, 0, SEEK_SET); // Seek back to the beginning 

    fseek(sourceFile, 0, SEEK_SET); // Seek back to the beginning 

    int currentChar; 

    while ((currentChar = fgetc(sourceFile)) != EOF) 
    { 
      fputc(currentChar, destinationFile); 
    } 

    fclose(sourceFile); 
    fclose(destinationFile); 
} 

我很樂意給你這個問題的更多細節,但我沒有太多的編程經驗C在Windows中,我真的不知道哪裏可能是問題。

回答

7

您應該使用b標誌給fopen:

fopen(source, "rb") 
fopen(destination, "wb"); 

據我瞭解,由於一些( 腦損傷 )主觀決定,在Win32輸入流達到0x1A的觸發EOF如果文件沒有以「二進制模式」打開。

編輯

在從來沒有看過,但現在有人告訴我,0x1A在DOS作爲軟EOF。

+0

這可能更多的腦損傷,然後主觀 - 用於EOF字符的原因是由於Windows的與CP/M史前連接只持續跟蹤文件的大小在一個部門(或羣集?)粒度。 –

+2

@邁克爾伯爾我真的很喜歡它,如果你有更多的信息。 – cnicutar

+0

沒有太多的信息 - CP/M只知道一個文本文件在磁盤上佔用了多少個扇區;要知道何時應該停止從最後一個扇區讀取數據,使用了一個定點EOF值,並且他們選擇了'ctrl-Z'作爲該定點。由於MS-DOS提供了與CP/M一定程度的兼容性,因此它支持相同的方案。而且由於Windows拉扯了很多DOS行李,我們就在這裏。 –

1

你需要使用「rb」和「wb」與fopen。

3

那麼,你不打開二進制模式下的文件(使用「wb」和「rb」)。這在Linux上並不重要,但它在Windows上運行,在文本模式下讀/寫文件時,它將轉換某些字節。例如:

\r\n <--> \n 

\x1a (Ctrl-Z) is treated as an EOF indicator