我有一个非常大的char数组,我需要将其转换为字符串才能在其上使用Regex
但是当我将它传递给字符串构造函数时,我得到OutOfMemoryException
这么大。
我知道字符串是 immutable ,因此不应该指定其基础字符集合,但是我需要一种方法来使用正则表达式而不复制整件事。
我如何获得该阵列?
StreamReader
从文件中获取的。我知道要阅读的内容的起始位置和长度,Read
和ReadBlock
方法需要我提供char[]
缓冲区。以下是我想知道的事情:
答案 0 :(得分:1)
如果您有可以搜索的字符或图案,保证不会出现在您尝试查找的图案中,则可以扫描该字符以查找该字符并创建较小的字符串以单独处理。过程将类似于:
char token = '|';
int start = 0;
int length = 0;
for(int i = 0; i < charArray.Length; i++;)
{
if(charArray[i] == token)
{
string split = new string(charArray,start,length);
// check the string using the regex
// reset the length
length = 0;
}
else
{
length++;
}
}
这样你就可以复制每次尝试后对整个字符串进行GC的字符串的较小段。
答案 1 :(得分:0)
我认为你最好的选择是将多个char []块读入与某个维度重叠的单个字符串。这样,您就可以在各个块上执行正则表达式,并且重叠将使您能够确保块中的“中断”不会破坏搜索模式。以伪代码的方式:
int chunkSize = 100000;
int overLap = 2000;
for(int i = 0; i < myCharArray.length; i += chunkSize - overlap)
{
// Grab your array chunk into a partial string
// By having your iteration slightly smaller than
// your chunk size you guarantee not to miss any
// character groupings. You just need to make sure
// your overlap is sufficient to cover the expression
string chunk = new String(myCharArray.Skip(i).Take(chunkSize).ToArray());
// run your regex
}
答案 2 :(得分:0)
一个相当丑陋的选择是使用非托管的RegEx库(如POSIX正则表达式库)和不安全的代码。您可以获取一个指向char数组的byte *指针,并将其直接传递给非托管库,然后封回响应。
fixed (byte * pArray = largeCharArray)
{
// call unmanaged code with pArray
}
答案 3 :(得分:-2)
如果您使用的是.NET 4.0或更高版本,那么您应该使用的是MemoryMappedFile。这个类是专门设计的,因此您可以操作非常大的文件。从MSDN文档:
内存映射文件将文件内容映射到应用程序 逻辑地址 空间。内存映射文件使程序员能够处理非常大的文件,因为 内存可以同时管理,它们允许完全随机访问文件 无需寻求。内存映射文件也可以跨多个共享 过程
获得内存映射文件后,请查看this Stack Overflow answer有关如何将RegEx应用于内存映射文件的信息。
希望这有帮助!