2016-06-27 6 views
2

J'ai le problème suivant: si le String contient une char qui ne connaît pas de ASCII, il utilise un 63.C# UTF8 codant pour bytearray hors de portée

En raison de ce que j'ai changé l'encodage à UTF8, mais Je sais qu'un char peut avoir le length de deux bytes, donc je reçois une erreur hors plage.
Comment puis-je résoudre le problème?

System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); 

byte[] baInput = enc.GetBytes(strInput); 

// Split byte array (6 Byte) in date (days) and time (ms) parts 
byte[] baMsec = new byte[4]; 
byte[] baDays = new byte[2]; 

for (int i = 0; i < baInput.Length; i++) 
{ 
    if (4 > i) 
    { 
     baMsec[i] = baInput[i]; 
    } 
    else 
    { 
     baDays[i - 4] = baInput[i]; 
    } 
} 
+1

Quel est le contenu de 'strInput'? – Toxantron

+0

Le contenu est par exemple: l|h * – xproseal

+0

Il semble que vous travaillez avec des octets, pas de texte. N'utilisez pas une chaîne pour la stocker en premier lieu, mais un tableau d'octets. Comment obtenez-vous le 'strInput' en premier lieu? – CodeCaster

Répondre

2

Le problème que vous semblez être HAVING est que vous connaissez le nombre de caractères, mais pas le nombre d'octets , en utilisant UTF8. Pour résoudre simplement ce problème, vous pouvez utiliser:

byte[] baMsec = Encoding.UTF8.GetBytes(strInput.SubString(0, 4)); 
byte[] baDays = Encoding.UTF8.GetBytes(strInput.SubString(4)); 
+0

le 'strInput' contient §║ ê ou l|h * – xproseal

+0

@xproseal merci, j'ai édité ma question quand j'ai vu des données d'échantillon. Il pourrait être sage d'essayer de comprendre quel encodage a été utilisé à l'origine pour construire ces données, et utilisez vous-même cet encodage. –

+0

Ma réponse * pas question: P –

0

Le problème est que votre baInput peut contenir plus de valeurs que les deux baDays et baMsec peut contenir. Après 6 itérations, vous n'avez plus de taille de tableau. Par conséquent, l'exception. Lorsque vous atteignez la septième itération, vous obtenez i - 4, ce qui donne 6 - 4 = 2.

Depuis baDays n'a que deux éléments, vous pouvez définir les valeurs sur l'index 0 et 1.

+0

Vous avez expliqué le problème, mais vous n'avez pas donné de solution. – Toxantron

+0

Cela dépend vraiment. Vous pouvez lire au maximum 6 octets, mais vous pouvez tronquer les données. Probablement, OP a besoin d'étendre le tableau pour que tous les caractères puissent être lus. Pour UTF-8 cela signifierait doubler la taille du tableau ferait l'affaire. Il est possible que ce soit une option pour empêcher que cela se produise en forçant les données à être en ASCII, puisque les données semblent être horodatées. –

1

Solution recommandée:

1) Diviser le strInput en utilisant la méthode SubString(Int32, Int32) et obtenir les pièces de date et d'heure dans les variables String distinctes, dites strDate et strTime.

2) Ensuite, appelez UTF8Encoding.GetBytes sur strDate et strTime et recueillir le tableau d'octets dans baDays et baMsec respectivement.

Pourquoi cela fonctionne:

C# String est par défaut UTF-16 codé, ce qui est tout aussi bon pour représenter les caractères non-ASCII. Par conséquent, aucune donnée n'est perdue.

Généralités Attention:

Ne jamais essayer de manipuler directement les chaînes codées à niveau octet, vous aurez perdu. Utilisez les méthodes de classe String et Encoding de C# pour obtenir les octets si vous voulez des octets.

autre approche:

Je me demande (comme d'autres) pourquoi vos données date-heure contient des caractères non numériques. J'ai vu dans un commentaire que vous obtenez vos données de reader["TIMESTAMP2"].ToString(); et le contenu de l'échantillon est §║ ê or l¦h. Vérifiez si vous interprétez des données numériques stockées dans reader["TIMESTAMP2"] comme String par erreur et devriez-vous réellement les traiter comme un type numérique. Sinon, même avec cette méthode, vous obtiendrez une sortie inattendue bientôt.

+0

[Cette réponse] (http://stackoverflow.com/a/38047841/993547) était déjà donnée il y a quelques minutes. –

+0

Je sais. Il est apparu pendant que je rédigeais ma réponse. Devrais-je supprimer le mien? –

+0

Ce serait une possibilité, oui. Vous pouvez également étendre votre réponse pour donner plus d'informations, informations qui n'ont pas été fournies dans une réponse précédente. Cela ferait ressortir votre réponse. –