2009-08-20 8 views
2

je le code suivant:Conversion de byte [] à chaîne

using (BinaryReader br = new BinaryReader(
     File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite))) 
{ 
    int pos = 0; 
    int length = (int) br.BaseStream.Length; 

    while (pos < length) 
    { 
     b[pos] = br.ReadByte(); 
     pos++; 
    } 

    pos = 0; 
    while (pos < length) 
    { 
     Console.WriteLine(Convert.ToString(b[pos])); 
     pos++; 
    } 
} 

Le FILE_PATH est une chaîne const qui contient le chemin d'accès au fichier binaire en cours de lecture. Le fichier binaire est un mélange d'entiers et de caractères. Les entiers ont chacun 1 octet et chaque caractère est écrit dans le fichier sous la forme de 2 octets.

Par exemple, le fichier a les données suivantes:

1HELLO SONT COMMENT YOU45YOU PROSPECTIFS // GRANDE SONT et ainsi de suite

S'il vous plaît noter: Chaque entier est associé à la chaîne de caractères suivants. Donc 1 est associé à "BONJOUR COMMENT ÊTES-VOUS" et 45 avec "VOUS REGARDEZ GRAND" et ainsi de suite.

Maintenant le binaire est écrit (je ne sais pas pourquoi mais je dois vivre avec ça) de telle sorte que '1' ne prendra qu'un octet alors que 'H' (et autres caractères) prend 2 octets chacun.

Voici donc ce que le fichier contient en fait:

0100480045..and ainsi de suite Heres la rupture:

01 est le premier octet pour l'entier 1 0048 sont les 2 octets pour « H »(H est 48 en hexadécimal) 0045 sont les 2 octets pour « E »(E = 0x45)

et ainsi de suite .. Je veux que ma console pour imprimer un format lisible sur ce fichier: ce que je veux pour imprimer "1 BONJOUR COMMENT ETES-VOUS" et puis "45 VOUS REGARDEZ GRAND" et ainsi de suite ..

Est-ce que ce que je fais est correct? Y a-t-il un moyen plus facile/efficace? Ma ligne Console.WriteLine (Convert.ToString (b [pos])); ne fait qu'imprimer la valeur entière et non le caractère réel que je veux. C'est OK pour les entiers dans le fichier mais comment puis-je lire les caractères?

Toute aide serait grandement appréciée. Merci

+0

langue? – mkoryak

+0

J'ai supprimé ma réponse - quelle était la personne pensant qui a décidé de ce format? : boggled: –

+0

Comment le champ entier est-il différencié de la chaîne? Les caractères peuvent-ils être au-dessus du point de code U + 00FF? L'entier peut-il être "0"? L'entier est-il signé ou non signé? – outis

Répondre

8

Je pense que ce que vous cherchez est Encoding.GetString.

Étant donné que vos données de chaîne est composée de 2 caractères d'octets, comment vous pouvez obtenir votre ficelle est:

for (int i = 0; i < b.Length; i++) 
{ 
    byte curByte = b[i]; 

    // Assuming that the first byte of a 2-byte character sequence will be 0 
    if (curByte != 0) 
    { 
    // This is a 1 byte number 
    Console.WriteLine(Convert.ToString(curByte)); 
    } 
    else 
    { 
    // This is a 2 byte character. Print it out. 
    Console.WriteLine(Encoding.Unicode.GetString(b, i, 2)); 

    // We consumed the next character as well, no need to deal with it 
    // in the next round of the loop. 
    i++; 
    } 
} 
+0

Vous devrez lire le premier octet "id" séparément, puis traduire le reste des octets en utilisant le codage approprié. – tvanfosson

+0

Oh, j'ai raté ce petit bout de question. Je vais éditer ma réponse. – paracycle

+0

Comment le code détermine-t-il la fin de la première chaîne? Sans cette information, vous ne saurez pas quand chercher le prochain numéro. –

1

Vous pouvez utiliser cordes System.Text.UnicodeEncoding.GetString() qui prend un octet [] array et produit une chaîne. I found this link very useful

+0

Vous devriez vraiment ajouter un résumé afin que votre réponse puisse se suffire à elle-même. Ce n'est pas mon downvote, mais je peux certainement comprendre pourquoi quelqu'un a pensé que ce n'était pas utile. – tvanfosson

0
using (BinaryReader br = new BinaryReader(File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite))) 
{  
    int length = (int)br.BaseStream.Length;  

    byte[] buffer = new byte[length * 2]; 
    int bufferPosition = 0; 

    while (pos < length)  
    {   
     byte b = br.ReadByte();   
     if(b < 10) 
     { 
      buffer[bufferPosition] = 0; 
      buffer[bufferPosition + 1] = b + 0x30; 
      pos++; 
     } 
     else 
     { 
      buffer[bufferPosition] = b; 
      buffer[bufferPosition + 1] = br.ReadByte(); 
      pos += 2; 
     } 
     bufferPosition += 2;  
    }  

    Console.WriteLine(System.Text.Encoding.Unicode.GetString(buffer, 0, bufferPosition)); 

}

+1

Je reçois les erreurs suivantes du compilateur lorsque j'essaie d'utiliser votre code à la ligne buffer [bufferPosition + 1] = b + 0x30; : erreur CS0266: Impossible de convertir le type 'int' en 'byte' implicitement. Une conversion explicite existe (manque-t-il un cast?) – zack

+0

J'ai également vérifié la valeur de la variable de longueur. Cela inclut le nombre de zéros. Donc je ne pense pas qu'il soit nécessaire de le multiplier par 2 au début comme vous l'avez fait. – zack

+0

Désolé, j'ai oublié de lancer la valeur hexadécimale, cette ligne doit être buffer [bufferPosition + 1] = b + (byte) 0x30; Vous devez toutefois multiplier la longueur du tampon par 2, car la taille globale du tableau peut doubler si la totalité de l'entrée est entière – LorenVS