37

我在 C# 中进行了大量的字符串操作,并且确实需要每个字符存储一个字节的字符串。这是因为我需要同时在内存中存储千兆字节的文本,这会导致内存不足的问题。我确定该文本永远不会包含非 ASCII 字符,因此出于我的目的,System.String 和 System.Char 将所有内容存储为每个字符两个字节的事实既不必要又是一个真正的问题。

我即将开始编写我自己的 CharAscii 和 StringAscii 类 - 字符串 1 基本上将其数据保存为 byte[],并公开类似于 System.String 所做的字符串操作方法。然而,这似乎需要做很多工作来做一些看起来像一个非常标准的问题,所以我真的在这里发帖以检查是否还没有更简单的解决方案。例如,是否有某种方法可以使 System.String 在内部将数据存储为我没有注意到的 UTF8,或者以其他方式解决问题?

4

4 回答 4

11

好吧,您可以创建一个包装器,将数据检索为 UTF-8 字节,并根据需要将片段转换为 System.String,反之亦然,将字符串推回内存。Encoding 类将帮助您:

var utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(myString);

var myReturnedString = utf8.GetString(utfBytes);
于 2012-08-27T15:09:13.960 回答
6

如您所见,CLR 使用 UTF-16 进行字符编码。您最好的选择可能是使用 Encoding 类和 BitConverter 来处理文本。这个问题有一些很好的例子可以在两种编码之间进行转换:

在 C# 中将字符串 (UTF-16) 转换为 UTF-8

于 2012-08-27T15:10:24.300 回答
3

并不真地。System.String专为存储字符串而设计。您的要求是具有特定内存优势的非常特殊的字符串子集。

现在,“具有特殊内存优势的非常特殊的字符串子集”出现了很多,但并不总是相同的非常特殊的子集。仅 ASCII 的代码不是供人类阅读的,因此它往往是短代码,或者可以以流处理方式处理的东西,或者是与字节合并的文本块做其他工作(例如,相当多的二进制格式将具有直接转换为 ASCII 的小位)。

因此,您有一个非常奇怪的要求。

当您谈到千兆字节部分时,更是如此。如果我正在处理演出,我会立即考虑如何停止处理演出,和/或获得比 50% 更可观的节省。我会考虑将我目前不感兴趣的块映射到文件,或者关于绳索,或者关于一堆其他事情。当然,这些适用于某些情况,而不适用于所有情况,所以再一次,我们不是在谈论 .NET 应该坚持作为一种万能的东西,因为一种尺寸不适合全部。

除此之外,仅 utf-8 位并不难。所有其他方法都变得有效。同样,您需要的东西与其他人不同。

于 2012-08-27T15:11:20.040 回答
0

正如我所看到的,您的问题是 C# 中的 char 占用 2 个字节,而不是 1 个。

读取文本文件的一种方法是使用以下命令打开它:

    System.IO.FileStream fs = new System.IO.FileStream(file, System.IO.FileMode.Open);
    System.IO.BinaryReader br = new System.IO.BinaryReader(fs);

    byte[] buffer = new byte[1024];
    int read = br.Read(buffer, 0, (int)fs.Length);

    br.Close();
    fs.Close(); 

这样您就可以从文件中读取字节。我尝试使用以UTF-8编码的 *.txt 文件(每个 char 2 个字节)和ANSI每个 char 1 个字节) 。

于 2012-08-27T15:37:30.937 回答