2014-06-28 128 views
0
public static byte[] ReadMemoryMappedFile(string fileName) 
    { 
     long length = new FileInfo(fileName).Length; 
     using (var stream = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite)) 
     { 
      using (var mmf = MemoryMappedFile.CreateFromFile(stream, null, length, MemoryMappedFileAccess.Read, null, HandleInheritability.Inheritable, false)) 
      { 
       using (var viewStream = mmf.CreateViewStream(0, length, MemoryMappedFileAccess.Read)) 
       { 
        using (BinaryReader binReader = new BinaryReader(viewStream)) 
        { 
         var result = binReader.ReadBytes((int)length); 
         return result; 
        } 
       } 
      } 
     } 
    } 

OpenFileDialog openfile = new OpenFileDialog(); 
     openfile.Filter = "All Files (*.*)|*.*"; 
     openfile.ShowDialog(); 
     byte[] buff = ReadMemoryMappedFile(openfile.FileName); 
     texteditor.Text = BitConverter.ToString(buff).Replace("-"," "); <----A first chance exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll 

嘗試讀取大文件時出現System.OutOfMemory異常。 我已經讀了很多在所有的網絡4周...並嘗試了很多!但是,我仍然無法找到解決我的問題的好辦法。 請幫助我..嘗試讀取大文件時發生System.OutOfMemory異常

更新

public byte[] FileToByteArray(string fileName) 
    { 
     byte[] buff = null; 
     FileStream fs = new FileStream(fileName, 
             FileMode.Open, 
             FileAccess.Read); 
     BinaryReader br = new BinaryReader(fs); 
     long numBytes = new FileInfo(fileName).Length; 
     buff = br.ReadBytes((int)numBytes); 
     //return buff; 
     return File.ReadAllBytes(fileName); 
    } 

OR

public static byte[] FileToByteArray(FileStream stream, int initialLength) 
    { 
     // If we've been passed an unhelpful initial length, just 
     // use 32K. 
     if (initialLength < 1) 
     { 
      initialLength = 32768; 
     } 
     BinaryReader br = new BinaryReader(stream); 
     byte[] buffer = new byte[initialLength]; 
     int read = 0; 

     int chunk; 
     while ((chunk = br.Read(buffer, read, buffer.Length - read)) > 0) 
     { 
      read += chunk; 

      // If we've reached the end of our buffer, check to see if there's 
      // any more information 
      if (read == buffer.Length) 
      { 
       int nextByte = br.ReadByte(); 

       // End of stream? If so, we're done 
       if (nextByte == -1) 
       { 
        return buffer; 
       } 

       // Nope. Resize the buffer, put in the byte we've just 
       // read, and continue 
       byte[] newBuffer = new byte[buffer.Length * 2]; 
       Array.Copy(buffer, newBuffer, buffer.Length); 
       newBuffer[read] = (byte)nextByte; 
       buffer = newBuffer; 
       read++; 
      } 
     } 
     // Buffer is now too big. Shrink it. 
     byte[] ret = new byte[read]; 
     Array.Copy(buffer, ret, read); 
     return ret; 
    } 

我仍然在試圖讀取大文件時得到一個System.OutOfMemory異常。

+0

請指定您的文件有多大。 – kobigurk

+0

鑑於您正在將所有內容都讀入內存,目前尚不清楚爲什麼要使用內存映射文件......並且您不僅將它讀入內存,而且還將它轉換爲十六進制,並且然後試圖顯示它。這將花費大量的內存。文件有多大? –

+0

我有大文件> 4GB,我想讀它。如何將大文件讀入字節數組爲hex? – FetFat

回答

1

如果您的文件是4GB,則BitConverter會將每個字節轉換爲XX字符串,每個字符串中的字符數爲2個字節* 3個字節* 4 294 967 295字節= 25 769 803 770.您需要+ 25Gb釋放內存以適應整個字符串,再加上您已將文件作爲字節數組存儲在內存中。

此外,在.NET程序沒有單個對象可以是超過2GB。字符串長度的理論限制是1,073,741,823個字符,但是您還需要有一個64位的過程。

所以解決你的情況 - 開放的FileStream。首先讀取16384字節(或多少可以適合您的屏幕),轉換爲十六進制並顯示,並記住文件偏移量。當用戶想要導航到一個或下一個頁面 - 搜尋到該位置上的磁盤文件,讀取並再次顯示等

+0

不錯的信息,謝謝?我是WPF的新手,謝謝 – FetFat

1

您需要閱讀數據塊中的文件,跟蹤您的文件在哪裏,頁面上的屏幕和使用尋求和位置的內容向上移動,文件流的下降。

0

您將無法顯示4GB的文件先讀所有的在內存中的任何方法。

的方法是虛擬化數據,只讀取可見線時用戶滾動。如果您需要執行只讀文本查看器,那麼您可以使用WPF ItemsControl進行堆棧面板的修改,並將其綁定到自定義IList集合,該集合將懶惰地從行索引計算文件偏移量的文件中獲取行。

+0

IM使用WPF,你能告訴我如何實現virtulizing堆疊面板並綁定到自定義的IList集合的十六進制查看器可以讀取一個大文件分成十六進制值 – FetFat

+0

以下是如何在ItemsControl中使用虛擬化堆棧面板http://stackoverflow.com/questions/2783845/virtualizing-an-itemscontrol - 這將虛擬化文本行。要虛擬化數據,您需要從IList 以及索引器this [int index]中派生一個類get - 通過偏移量導航到您需要顯示的文件中的位置,將數據完全按照行寬讀入緩衝區並返回它的十六進制字符串。 –

相關問題