簡體   English   中英

需要幫助管理大文件

[英]Need help managing large files

我想讀取4GB文件並通過在某些字段中進行更改來創建它的副本。 我的首要任務是時間效率,即處理應該快。
我想將其加載到內存中,以便快速進行讀/寫操作。 我應該用堆嗎? 還是我應該嘗試其他類似內存映射文件的東西? 或其他任何出路?

首先感謝大家的貢獻...讓我重新思考我的問題...
我必須從用戶那里獲取一個文件,該文件大約為3-4GB。 它包含記錄,每個記錄都有一些字段,這些字段包含一些敏感數據,我需要對其進行搜索和加密直到EOF。
如果我使用FILE I / O執行搜索和加密,它將永遠需要..作為其批處理...。因此,當我在64位OS上工作時,我可以在堆上創建一個4GB的陣列,加載整個文件並執行操作。 此本地副本將提供比FILE IO更好的性能...
我正在考慮使用內存映射的文件,因為它將消除對數組(本地副本)的需要,並且操作速度也不錯,但是我不熟悉它,因此詢問是否適合上述情況……!
我也在考慮考慮MATLAB ...您也可以建議您是否有更好的出路..thnx ...

我的猜測是采用內存映射的方法,但是您應該真正嘗試一下,並衡量哪種方法可以為您提供最佳性能。 從天真的簡單實施開始,如果這還不夠好,請嘗試對其進行優化。

該解決方案很簡單,但是需要您提供一些有關給定文件格式詳細信息的信息。

但是,一些通用解決方案的偽代碼(普通C,需要時要求C ++實現):

#define BUFSIZE 4096 // 4k, try larger or smaller values to improve performance...

int process_file( const char* filename ) {
  char buffer[BUFSIZE];
  size_t nread;
  FILE* fp;
  if( (fp=fopen(filename,"rb"))==NULL ) return 1;
  while( (nread=fread(buffer,1,BUFSIZE,fp))>=0 ) {
    if( nread==0 ) break; // EOF
    process_file_buffer( buffer, nread );
  }
  fclose(fp);
  return nread>=0 ? 0 : 2; // 0==success, 2==read error, check "errno"!
}

void process_file_buffer( const char* buffer, size_t size ) {
  // process, and write result to target file
}

編輯

關於您的內存管理問題的疑問:這在很大程度上取決於您的實際代碼和實際需求。 在我的示例代碼中,只有一個緩沖區會自動分配到堆棧中,這對於該用例來說已經足夠了。

但是,如果您有特殊要求,請明確詢問它們!

另一個編輯:

這段代碼很扎實,為更多內容提供了理想的基礎。 但是:如果您將遇到性能問題,那么您實際上必須運行分析器(或編寫&自己的分析代碼)。

為什么?

您可能會懷疑此代碼是瓶頸,但我敢打賭它不會成為瓶頸;)不要忘記,您還必須向DISK寫一些東西,也不要忘記必須傳遞任何單個字節。通過內存(然后從那里通過CPU寄存器)對文件進行處理(這是您的實際要求之一...)。

SO:現在還不介意內存映射的IO。 首先,您必須考慮其他事項;)

您可能不喜歡這樣。 但這只是您的初始情況。

並且,在開始考慮內存管理之前,您應該開始考慮實際的I..O ..要求。

還需要編輯:

吻-保持簡單,愚蠢;-)

從問題的描述中,我不確定您可以避免不良的I / O性能。 如果您必須掃描4gb的數據以獲取所需的記錄,然后再次將整個文件寫出,我懷疑如果您使用普通的文件I / O或mmap會不會太大,因為瓶頸將讀取數據關閉磁盤。 在這兩種情況下,內核都會嘗試緩存文件的頻繁訪問部分,因此重新讀取很快。

聽起來您想要文件系統提供某種形式的寫時復制支持,但這將高度依賴於文件系統功能(如果它們完全存在)。

您可以嘗試將mmap與MAP_PRIVATE一起使用。 首先,將源文件映射到內存中。 所做的任何更改都將僅保留在內存中(MAP_PRIVATE),但文件的所有未觸及部分都將從原始文件中備份(如果不觸摸,則可減少內存壓力)。 然后,您將不得不使用通過映射的內存的普通文件I / O來寫出新文件。 但是我懷疑內核是否足夠聰明以發現任何不需要的復制。

正如其他人指出的那樣,對於這種大小的文件,將需要64位體系結構一次映射整個文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM