36 votes

Stockage d'une chaîne au format UTF8 en C #

Je suis en train de faire beaucoup de manipulation de chaîne en C#, et a vraiment besoin de chaînes pour être stocké sur un octet par caractère. C'est parce que j'ai besoin de giga-octets de texte simultanément dans la mémoire et il est à l'origine de basse problèmes de mémoire. Je sais bien que ce texte ne sera jamais contiennent des caractères non-ASCII, donc pour ma part, le fait que le Système de.Chaîne et du Système.Char stocker tout ce que les deux octets par caractère est à la fois inutile et un réel problème.

Je suis sur le point de commencer à coder mon propre CharAscii et StringAscii classes - la chaîne de l'un va tenir ses données sous forme de byte[], et de les exposer à la manipulation de chaînes de méthodes similaires à celles de ce Système.Chaîne. Toutefois, cela semble beaucoup de travail à faire quelque chose qui semble être une très standard de problème, donc je suis vraiment à poster ici pour vérifier qu'il n'y a pas déjà une solution plus facile. Est-il par exemple d'une certaine façon je peux faire Système.Chaîne interne de stocker des données comme UTF8 que je n'ai pas remarqué, ou d'un autre moyen de les contourner le problème?

11voto

KeithS Points 36130

Eh bien, vous pouvez créer un wrapper qui récupère les données sous forme d'octets UTF-8 et convertit les morceaux selon les besoins en System.String, puis vice-versa pour repousser la chaîne en mémoire. La classe Encoding vous aidera ici:

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

var myReturnedString = utf8.GetString(utfBytes);
 

6voto

Chris Points 1869

Comme vous l'avez constaté, le CLR utilise UTF-16 pour l'encodage des caractères. Votre meilleur pari peut être d'utiliser les classes d'encodage et un BitConverter pour gérer le texte. Cette question contient de bons exemples de conversion entre les deux encodages:

Convertir une chaîne (UTF-16) en UTF-8 en C #

2voto

Jon Hanna Points 40291

Pas vraiment. System.String est conçu pour stocker des chaînes de caractères. Votre exigence est très sous-ensemble particulier de chaînes avec notamment la mémoire des avantages.

Maintenant, "très sous-ensemble particulier de chaînes avec notamment la mémoire des avantages" revient beaucoup, mais pas toujours le même très sous-ensemble particulier. Code ASCII-seulement n'est pas pour la lecture par les êtres humains, de sorte qu'il a tendance à être soit à court codes, ou quelque chose qui peut être traité dans un flux de traitement de la manière ou l'autre des segments de texte fusionné avec les octets de faire d'autres travaux (par exemple, tout à fait un peu binaire, les formats ont de petits morceaux qui se traduisent directement en code ASCII).

En tant que tel, vous avez une jolie exigence de l'étrange.

D'autant plus quand vous venez à la giga-octets de la partie. Si je fais face à des concerts, je suis immédiatement penser à comment je peux arrêter d'avoir à traiter avec des concerts, et/ou obtenir beaucoup plus sérieuses économies de 50%. J'avais penser à la cartographie des morceaux je ne suis pas intéresse actuellement dans un fichier ou sur des cordes, ou sur un tas d'autres choses. Bien sûr, ceux qui vont travailler pour certains cas et pas pour tous, donc, encore une fois, nous ne parlons pas de quelque chose où .NET devrait s'en tenir à quelque chose comme un one-size-fits-all, en raison de la taille unique ne sera pas adapté à tous.

Au-delà de cela, juste de l'utf-8 bits n'est pas si difficile. C'est toutes les autres méthodes qui devient de travail. Encore une fois, ce que vous avez besoin, il ne va pas être le même que quelqu'un d'autre.

1voto

Thanatos Points 719

Comme je peux voir votre problème, c'est que le caractère en C # occupe 2 octets, au lieu d'un.

Une façon de lire un fichier texte est de l'ouvrir avec:

     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(); 
 

Et de cette façon, vous lisez les octets du fichier. Je l'ai essayé avec des fichiers * .txt encodés en UTF-8 , soit 2 octets par caractère , et ANSI , 1 octet par caractère .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X