web-dev-qa-db-ja.com

C#で文字列をUTF8として保存する

私はC#で多くの文字列操作を行っており、文字列を文字ごとに1バイトで保存する必要があります。これは、メモリ内にギガバイトのテキストを同時に必要とし、メモリ不足の問題を引き起こしているためです。このテキストには非ASCII文字が含まれないことは確かです。したがって、私の目的では、System.StringとSystem.Charが文字ごとに2バイトとしてすべてを格納するという事実は不要であり、実際の問題でもあります。

独自のCharAsciiクラスとStringAsciiクラスのコーディングを開始しようとしています-文字列クラスは基本的にデータをbyte []として保持し、System.Stringのような文字列操作メソッドを公開します。しかし、これは非常に標準的な問題のように思われる何かを行うための多くの作業のように思えるので、私は本当に簡単な解決策がないことを確認するためにここに投稿しています。たとえば、System.Stringに、気付いていないUTF8としてデータを内部的に保存する方法、または問題を回避する他の方法がありますか?

34
PhantomDrummer

ご覧のとおり、CLRは文字エンコードにUTF-16を使用します。最善の策は、エンコードクラスとBitConverterを使用してテキストを処理することです。この質問には、2つのエンコーディング間の変換の良い例がいくつかあります。

C#で文字列(UTF-16)をUTF-8に変換

6
Chris

さて、データをUTF-8バイトとして取得し、必要に応じて断片をSystem.Stringに変換するラッパーを作成し、その逆の場合は文字列をメモリにプッシュアウトします。 Encodingクラスはここで役立ちます:

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

var myReturnedString = utf8.GetString(utfBytes);
11
KeithS

あんまり。 System.Stringは、文字列を保存するために設計されています。あなたの要件は、特定のメモリの利点を持つ文字列の非常に特定のサブセットです。

現在、「特定のメモリの利点を持つ文字列の非常に特定のサブセット」が多く登場しますが、常に同じ特定のサブセットではありません。 ASCIIのみのコードは人間が読むためのものではないため、短いコードか、ストリーム処理の方法で処理できるもの、または他のジョブを実行するバイトとマージされたテキストチャンク(たとえば、かなりの数のバイナリ形式には、ASCIIに直接変換される小さなビットがあります)。

そのため、かなり奇妙な要件があります。

ギガバイトの部分に来るときはなおさらです。ギグに取り組んでいるのなら、ギグに対処するのをやめる方法をすぐに考えています。現在、ファイルに興味のないチャンクのマッピング、ロープ、またはその他のことについて考えています。もちろん、これらはすべてではなく、いくつかのケースで機能するため、1つのサイズが収まらないため、.NETが1つのサイズに収まるように何かを固定する必要があることについては話していません。すべて。

それ以上に、utf-8ビットだけはそれほど難しくありません。他のすべてのメソッドが機能します。繰り返しますが、あなたがそこに必要なものは他の誰かと同じではありません。

2
Jon Hanna

あなたの問題を見ることができるように、C#のcharは1バイトではなく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(); 

このようにして、ファイルからバイトを読み取ります。 TF-8でエンコードされた* .txtファイルで試してみました2バイト/文字、および[〜#〜] ansi [〜#〜]つまり1文字につき1バイトです。

1
Thanatos