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周了很多...并且尝试了很多!!!但是,我似乎无法找到解决问题的好方法。 请帮帮我..
更新
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 :(得分:1)
您需要以块的形式读取文件,跟踪文件的位置,在屏幕上分页内容并使用搜索和位置在文件流中上下移动。
答案 1 :(得分:1)
如果你的文件是4GB,那么BitConverter会把每个字节变成XX字符串,字符串中的每个字符串都是2字节*每字节3个字符* 4 294 967 295字节= 25 769 803 770.你需要+ 25Gb的免费内存以适应整个字符串,另外你已经将你的文件作为字节数组存储在内存中。
此外,.Net程序中没有单个对象可能超过2GB。字符串长度的理论限制为1,073,741,823个字符,但您还需要64位进程。
在您的情况下解决方案 - 打开FileStream。首先读取16384个字节(或者可以在屏幕上显示多少),转换为十六进制并显示,并记住文件偏移量。当用户想要导航到下一页或上一页时 - 在磁盘上的文件中寻找该位置,再次阅读和显示等。
答案 2 :(得分:0)
您无法通过任何方法首先在内存中显示所有内容的4Gb文件。
方法是虚拟化数据,在用户滚动时仅读取可见行。如果你需要做一个只读的文本查看器,那么你可以使用WPF ItemsControl与虚拟化堆栈面板并绑定到自定义IList集合,它将从文件计算文件的偏移量中为行索引延迟提取行。