Contrairement aux réponses données ici, vous n'avez pas besoin de vous soucier de l'encodage. _si_ les octets n'ont pas besoin d'être interprétés !
Comme vous l'avez mentionné, votre but est, simplement, de "récupérer les octets dans lesquels la chaîne a été stockée" .
(Et, bien sûr, être capable de reconstruire la chaîne de caractères à partir des octets).
Pour ces objectifs, je fais honnêtement no comprendre pourquoi les gens ne cessent de vous dire que vous avez besoin des encodages. Vous n'avez certainement PAS besoin de vous soucier des encodages pour cela.
Fais ça à la place :
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
// Do NOT use on arbitrary bytes; only use on GetBytes's output on the SAME system
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
Tant que votre programme (ou d'autres programmes) ne tente pas de interpréter les octets d'une manière ou d'une autre, ce que vous n'avez manifestement pas mentionné avoir l'intention de faire, il y a alors rien Cette approche n'est pas mauvaise ! Se préoccuper des codages ne fait que vous compliquer la vie sans raison réelle.
Avantage supplémentaire de cette approche : Peu importe que la chaîne contienne des caractères invalides, car vous pouvez toujours récupérer les données et reconstruire la chaîne d'origine !
Il sera codé et décodé de la même façon, parce que vous êtes juste en regardant les octets .
Mais si vous aviez utilisé un encodage spécifique, vous auriez eu des problèmes avec l'encodage/décodage de caractères invalides.
2 votes
Votre confusion sur le rôle de l'encodage me fait me demander si c'est la bonne question. Pourquoi essayez-vous de convertir une chaîne de caractères en un tableau d'octets ? Qu'allez-vous faire avec le tableau d'octets ?
0 votes
Je vais le crypter. Je peux le crypter sans le convertir, mais j'aimerais quand même savoir pourquoi le codage entre en jeu ici. Donnez-moi juste les octets, c'est ce que je dis.
6 votes
Si vous le cryptez, vous devrez toujours connaître le codage après le décryptage afin de savoir comment réinterpréter ces octets en une chaîne de caractères.
28 votes
Chaque chaîne est stockée comme un tableau d'octets, n'est-ce pas ? Pourquoi ne puis-je pas simplement avoir ces octets ?
2 votes
Jetez un coup d'oeil au site de Jon Skeet réponse dans un post avec le question précise . Cela expliquera pourquoi vous dépendez de l'encodage.
3 votes
Je pense qu'Anthony essaie d'aborder la déconnexion fondamentale dans <300 chars. Vous supposez une représentation interne cohérente d'une chaîne, alors qu'en fait cette représentation peut être n'importe quoi. Pour créer, et éventuellement décoder, le bytestream, vous devez choisir un encodage à utiliser.
2 votes
"Une chaîne de caractères est un tableau de caractères, où un caractère n'est pas un octet dans le monde .Net" Très bien, mais quel que soit l'encodage, chaque caractère correspond à un ou plusieurs octets. Puis-je avoir ces octets sans avoir à spécifier un encodage ?
148 votes
L'encodage es ce qui fait correspondre les caractères aux octets. Par exemple, en ASCII, la lettre "A" correspond au nombre 65. Dans un autre codage, ce ne sera peut-être pas la même chose. L'approche de haut niveau des chaînes de caractères adoptée dans le cadre de .NET rend cet aspect peu pertinent (sauf dans ce cas).
3 votes
Vous pouvez choisir la voie la plus simple et utiliser UTF-8 des deux côtés.
6 votes
Dans le cas de .NET, la solution de facilité consiste à utiliser UTF-16 des deux côtés, puisque c'est ce que .NET utilise en interne.
22 votes
Pour jouer l'avocat du diable : Si vous vouliez obtenir les octets d'une chaîne en mémoire (comme .NET les utilise) et les manipuler d'une manière ou d'une autre (par exemple, CRC32), et ne JAMAIS JAMAIS vouloir les décoder à nouveau dans la chaîne d'origine... il n'est pas évident de savoir pourquoi vous vous souciez des codages ou comment choisir celui à utiliser.
88 votes
Je suis surpris que personne n'ait encore donné ce lien : joelonsoftware.com/articles/Unicode.html
1 votes
@Bevan : en date du 23 janvier 2009, vous arrivez en retard à la fête ;-) stackoverflow.com/questions/472906/net-string-to-byte-array-c/
0 votes
Duplicata possible de Comment convertir une chaîne de caractères en un tableau d'octets en .Net ?
8 votes
@AgnelKurian, A
char
est unstruct
que ça arrive comme ça à actuellement stocker des valeurs sous la forme d'un nombre de 16 bits (UTF-16). Ce que vous demandez réellement (obtenir les octets de caractères) n'est pas théoriquement possible parce que cela n'existe pas théoriquement. Achar
ostring
n'a pas de codage par définition. Et si la représentation de la mémoire changeait en UTF-32 ? Votre "récupérer les octets, les renvoyer" échouerait. due à l'encodage parce que vous avez évité l'encodage . Alors "Pourquoi cette dépendance à l'encodage ? !!!" Dépendez du codage pour que votre code soit fiable.35 votes
Un char n'est pas un byte et un byte n'est pas un char. Un caractère est à la fois une clé dans une table de polices et une tradition lexicale. Une chaîne de caractères est une séquence de caractères. (Les mots, les paragraphes, les phrases et les titres ont également leurs propres traditions lexicales qui justifient leurs propres définitions de type - mais je m'égare). Comme les entiers, les nombres à virgule flottante et tout le reste, les caractères sont codés en octets. Il fut un temps où l'encodage était simple, de un à un : L'ASCII. Cependant, pour tenir compte de toute la symbologie humaine, les 256 permutations d'un octet étaient insuffisantes et des codages ont été conçus pour utiliser sélectivement plus d'octets.
0 votes
@usr : vous venez d'invalider presque toutes les réponses avec votre modification, et vous avez également rendu plus difficile pour les gens de trouver cette question avec leur requête de recherche naturelle (mais vous l'avez probablement fait intentionnellement).
0 votes
@Mehrdad les réponses existantes étaient déjà invalides (pas ce qui était demandé). La vôtre est à peu près la seule réponse qui réponde réellement à la question posée. (Je vous recommande cependant de modifier votre réponse pour inclure quelques avertissements sur le fait que cette approche n'est vraiment presque jamais la meilleure).
9 votes
Quatre ans plus tard, je maintiens mon commentaire initial sur cette question. C'est fondamentalement imparfait parce que le fait que nous parlions d'une chaîne de caractères implique une interprétation . L'encodage de cette chaîne est une partie implicite du contrat sérialisé, sinon ce n'est qu'un tas de bits sans signification. Si vous voulez des bits sans signification, pourquoi les générer à partir d'une chaîne ? Il suffit d'écrire un tas de 0 et d'en finir.
0 votes
@Greg D, Disons que mon client possède des nombres à virgule flottante dans un format exotique utilisé pour stocker des distances astronomiques. Il n'utilise que ce seul format. Il veut que je me charge d'écrire et de lire ces nombres. Je ne les interprète pas. Mon client interprète les nombres et tout ce qu'il doit me donner, ce sont les octets que je dois écrire. En lecture, tout ce dont il a besoin de ma part, ce sont les octets que j'ai écrits. Stocker un indicateur de format à chaque fois en plus des octets est un gaspillage d'espace lorsqu'il utilise un seul format pour tous les nombres.
4 votes
@Agnel Kurian : Si vous écrivez des données binaires arbitraires, écrivez des données binaires. Cela n'a rien à voir avec la question initiale (qui concerne fondamentalement la sérialisation d'une chaîne).
0 votes
@GregD donc vous voulez stocker le même encodage 1000 fois pour 1000 chaînes différentes ?
7 votes
@AgnelKurian : Vous vous moquez de moi ? Cette question n'a pas de sens. Je pourrais en déduire que vous vouliez dire quelque chose comme : " ... stocker des informations sur l'encodage qui a été utilisé 1000 fois pour 1000 chaînes différentes. " Personne n'a jamais parlé de faire cela, cependant, et cela a été explicitement nié plus tôt quand j'ai dit "L'encodage de cette chaîne est un implicite une partie du contrat sérialisé..." donc vous ne pouviez pas vouloir dire ça.
3 votes
@AgnelKurian "Il veut que je m'occupe d'écrire et de lire ces chiffres. Je ne les interprète pas." - Si vous ne les interprétiez pas, vous auriez des octets et non des "chiffres". Alors, votre question disparaît. Si vous avez des "nombres", cela signifie que vous les avez déjà interprétés/décodés et que vous avez jeté les données originales en octets. Et maintenant, vous voulez essayer de reconstruire les données (coder), ce qui n'est peut-être même pas possible. Et si les nombres étaient en fait en base 10 et qu'en les entassant dans des flottants en base 2, vous les avez détruits pour toujours ? Vous ne voulez pas coder ? Ne décodez pas alors. Vous voulez des octets ? Alors utilisez des octets.
3 votes
Est-ce que vous supposez que
System.Text.Encoding.Unicode.GetBytes();
fait une sorte de conversion coûteuse que vous voulez éviter ? Si c'est le cas, votre hypothèse est fausse.4 votes
Votre premier commentaire (citation) : Chaque chaîne de caractères est stockée comme un tableau d'octets, n'est-ce pas ? Pourquoi ne puis-je pas simplement avoir ces octets ? Non, chaque chaîne est (plus ou moins) stockée comme un tableau de 16-bit unités de code qui correspondent à l'UTF-16. Il y aura des paires de substituts si votre chaîne contient des caractères Unicode en dehors du plan 0. Vous pouvez obtenir cette représentation facilement :
var array1 = yourString.ToCharArray();
Si, pour une raison quelconque, vous voulez que les unités de code commeUInt16
valeurs, faitesvar array2 = Array.ConvertAll<char, ushort>(array1, x => x);
. C'est unushort[]
là.0 votes
L'encodage est nécessaire parce que la taille - en octets - des caractères représentés en dépend, et non seulement parce que sizeof(char) est différent pour par exemple ASCII (1 octet) et WideString(2 octets), mais parce qu'il peut même varier - en cas d'UTF-8, un caractère est représenté comme suit 1 à 4 octets
5 votes
Ne pas se soucier de l'encodage est une chose. Ne pas vouloir spécifier un encodage en est une autre. Si ce qui vous frustre est de savoir quel encodage vous devez utiliser, choisissez-en un et utilisez-le tout le temps pour les conversions entre chaîne de caractères et tableau d'octets et tableau d'octets et chaîne de caractères. Par exemple, utilisez toujours Unicode, ou UTF-8. Votre choix. Une fois que vous avez choisi un encodage, vous n'avez plus à vous inquiéter et votre problème est résolu. Mais si votre frustration vient de la nécessité de spécifier un encodage, alors vous feriez mieux de vous y habituer, car que vous le vouliez ou non, un encodage a lieu.
5 votes
Vous devez toujours vous soucier de l'encodage de votre chaîne de caractères dans le tableau d'octets. L'hypothèse selon laquelle la chaîne est représentée en mémoire par un tableau d'octets est arbitraire. C'est ce qui se passe dans l'implémentation actuelle de .net. Personne ne peut vous garantir qu'elle ne changera pas à l'avenir pour une implémentation de listes liées (ou toute autre structure de données exotique). Même si vous utilisez le même système et le même programme pour relire les données cryptées, il y a toujours une chance qu'un futur patch de .net casse tout parce que vous n'avez pas spécifié explicitement dans quel encodage vous travaillez.