Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将字符串存储为C中的UTF8#_C#_.net_String_Utf 8_Ascii - Fatal编程技术网

C# 将字符串存储为C中的UTF8#

C# 将字符串存储为C中的UTF8#,c#,.net,string,utf-8,ascii,C#,.net,String,Utf 8,Ascii,我在C#中进行了大量的字符串操作,并且确实需要将字符串存储为每个字符一个字节。这是因为我需要在内存中同时存储千兆字节的文本,这会导致内存不足。我确信这个文本永远不会包含非ASCII字符,所以就我而言,System.String和System.Char将所有内容存储为每个字符两个字节的事实是不必要的,也是一个真正的问题 我即将开始编写我自己的CharAscii和StringAscii类——stringone基本上将其数据保存为byte[],并公开类似于System.string的字符串操作方法。然

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


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

好的,您可以创建一个包装器,以UTF-8字节的形式检索数据,并根据需要将数据段转换为System.String,然后反过来将字符串推回到内存中。编码类将在以下方面帮助您:

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

var myReturnedString = utf8.GetString(utfBytes);

正如您所发现的,CLR使用UTF-16进行字符编码。您最好使用编码类&位转换器来处理文本。这个问题有一些在两种编码之间转换的好例子:


不太可能<代码>系统。字符串用于存储字符串。您的需求是具有特定内存优势的非常特定的字符串子集

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

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

更重要的是,当你谈到千兆字节的部分。如果我处理的是演唱会,我会立即思考如何停止处理演唱会,和/或获得比50%更大的节约。我会考虑将我目前不感兴趣的块映射到一个文件,或者关于rope,或者其他一些东西。当然,这些方法在某些情况下有效,而不是在所有情况下都有效,因此,我们再次强调,我们不是在讨论.NET应该作为“一刀切”的方法来坚持的东西,因为“一刀切”不能适用于所有情况


除此之外,仅utf-8位并没有那么难。所有其他的方法都是可行的。同样,你需要的不是其他人。

正如我所看到的,你的问题是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文件进行了尝试,即2字节/字符,以及ANSI1字节/字符

的.NET是最好的方法吗?似乎C/C++是处理内存中巨大字符串的更好选择。Jon Skeet去年研究的这篇@Jon的文章很好,但它实际上只关注内存使用的详细分析,而不是取代字符串本身。另外,FWIW、Jon在文章上贴上了“古怪想法”和“邪恶代码”标签。如果你有Reflector或类似的东西,你可以从框架中取出
字符串
类的副本,并将其内部结构更改为使用字节数组。@RobertHarvey-我也会这样做,不幸的是,它不包含最有趣的位,比如著名的InternalMarvin32HashString()方法(我发誓这个方法存在:-),更严重的是,很多东西都是不安全的和/或内部CLR调用。+1,我自己在为一家房地产公司收集大量数据和这个解决方案时调查了这个问题,虽然有点不可思议,看起来很简陋,这几乎是我在C#中能想到的最好的东西。顺便说一句,这最终会变成UTF-16编码的字符串对象。@Tigran,如果你打算在任何时候使用System.string,就没有办法绕过它。但是,您可以从编码的字节数组中取出子部分,并以可控的方式将它们写出来,从而为您占用的资源数量留下一个上限。@Tigran请详细说明。utf8不是真正的utf8?@Tigran-是的,它是。除非OP想要完全放弃你通过.NET Framework免费获得的所有关于字符串的内容(我强烈建议你不要这样做),否则至少他正在使用的一些数据必须转换成UTF-16 System.String才能使用它。但是,他处理的大量数据可以保持UTF-8格式(如果他确实确定数据不会包含任何非ASCII字符,甚至可以使用ASCII),这并不奇怪。OP需要的字符串的工作方式与
System.String
相同,但占用了一半的空间。换言之,替换率下降。@RobertHarvey是的,但他们不想要O(n)长度,因为他们知道他们不需要O(n)长度,因为他们知道他们的数据。对基于utf-8的字符串有类似但不完全相同需求的人将需要O(n)计数,因为他们不仅仅坚持ASCII。一般的问题会出现很多,但细微的细节却各不相同,这使得一个人可以完美地替代另一个人的毒药。乔恩-我所做的,非常粗略地说,涉及到文本之间大量的交叉引用。因此,在处理过程中很难避免将整个文本存储在内存中。将我不感兴趣的块写入一个文件,只需将它们读回一毫秒