如何从char数组创建一个字符串而不复制它?

时间:2012-10-30 19:21:41

标签: c# .net arrays string char

我有一个非常大的char数组,我需要将其转换为字符串才能在其上使用Regex 但是当我将它传递给字符串构造函数时,我得到OutOfMemoryException这么大。

我知道字符串是 immutable ,因此不应该指定其基础字符集合,但是我需要一种方法来使用正则表达式而不复制整件事。

我如何获得该阵列?

  • 我是使用StreamReader从文件中获取的。我知道要阅读的内容的起始位置和长度,ReadReadBlock方法需要我提供char[]缓冲区。

以下是我想知道的事情:

  • 有没有办法指定字符串的底层集合? (它甚至将其字符保留在数组中吗?)
  • ...或直接在char数组上使用Regex?
  • ...或直接将文件的一部分作为字符串?

4 个答案:

答案 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应用于内存映射文件的信息。

希望这有帮助!