2009-05-31 6 views
2
byte[] header = new byte[]{255, 216}; 

string ascii = Encoding.ASCII.GetString(header); 

j'attends ASCII soit égal à être FFD8 (marqueur JPEG SOI)C# et Encoding.ASCII.GetString

Au lieu de cela je reçois "????"

+0

Où voyez-vous "????" ? ... Notez que 0xFFD8 n'est pas imprimable. –

+0

Modifiez la question en ajoutant vos nouvelles informations ci-dessous. Je pense que vous avez posé la mauvaise question peut-être? Peut-être mieux de faire une toute nouvelle question où vous posez la vraie question ... "écrire une fonction qui détermine si un fichier est une image basée uniquement sur les informations d'en-tête" – TheSoftwareJedi

Répondre

11

Dans ce cas, vous feriez mieux de comparer les tableaux d'octets plutôt que de convertir en chaîne.

Si vous devez convertir en chaîne, je suggère d'utiliser le codage Encodage Latin-1 alias ISO-8859-1 alias Code, car ce codage mappera tous les octets avec des valeurs hexadécimales comprises entre 0 et 255 à la Caractère Unicode avec la même valeur hexadécimale - pratique pour ce scénario. Tout des messages suivants obtenir ce encodage:

Encoding.GetEncoding(28591) 
Encoding.GetEncoding("Latin1") 
Encoding.GetEncoding("ISO-8859-1") 
+0

Pourquoi les tableaux d'octets? – iasksillyquestions

+2

Parce que ce sont des données binaires, les fichiers JPEG ne sont pas des textes, donc ne devraient pas être convertis en texte. –

8

Oui, c'est parce que ASCII est seulement de 7 bits - il ne définit aucune valeur au-dessus de 127. Les codages décodent typiquement les valeurs binaires inconnues à '?' (bien que cela puisse être changé en utilisant DecoderFallback). Si vous êtes sur le point de mentionner "extended ASCII" je suspecte que vous voulez réellement Encoding.Default qui est "la page de code par défaut pour le système d'exploitation" ... code page 1252 sur la plupart des systèmes occidentaux, je crois.

Quels caractères attendiez-vous?

EDIT: Selon la réponse acceptée (je suppose que la question a été modifiée après avoir ajouté ma réponse, je ne me souviens pas avoir vu JPEG à l'origine) vous ne devriez pas convertir les données binaires en texte. . Les données JPEG sont binary data - vous devriez donc vérifier les octets réels par rapport aux octets attendus.

Chaque fois que vous convertissez des données binaires arbitraires (images, musique ou vidéo) en texte à l'aide d'un codage simple (ASCII, UTF-8, etc.), vous risquez de perdre des données. Si vous avez pour le convertir en texte, utilisez Base64 qui est agréable et sûr. Si vous voulez juste le comparer avec les données binaires attendues, il vaut mieux ne pas le convertir en texte du tout.

EDIT: Ok, voici une classe pour aider la méthode de détection d'image pour un tableau d'octets donné. Je ne l'ai pas fait spécifique à HTTP; Je ne suis pas entièrement sûr si vous devriez vraiment aller chercher le InputStream, en lire juste un peu, puis récupérer le flux à nouveau. J'ai esquivé le problème en collant à des tableaux d'octets :)

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Linq; 

public sealed class SignatureDetector 
{ 
    public static readonly SignatureDetector Png = 
     new SignatureDetector(0x89, 0x50, 0x4e, 0x47); 

    public static readonly SignatureDetector Bmp = 
     new SignatureDetector(0x42, 0x4d); 

    public static readonly SignatureDetector Gif = 
     new SignatureDetector(0x47, 0x49, 0x46); 

    public static readonly SignatureDetector Jpeg = 
     new SignatureDetector(0xff, 0xd8); 

    public static readonly IEnumerable<SignatureDetector> Images = 
     new ReadOnlyCollection<SignatureDetector>(new[]{Png, Bmp, Gif, Jpeg}); 

    private readonly byte[] bytes; 

    public SignatureDetector(params byte[] bytes) 
    { 
     if (bytes == null) 
     { 
      throw new ArgumentNullException("bytes"); 
     } 
     this.bytes = (byte[]) bytes.Clone(); 
    } 

    public bool Matches(byte[] data) 
    { 
     if (data == null) 
     { 
      throw new ArgumentNullException("data"); 
     } 
     if (data.Length < bytes.Length) 
     { 
      return false; 
     } 
     for (int i=0; i < bytes.Length; i++) 
     { 
      if (data[i] != bytes[i]) 
      { 
       return false; 
      } 
     } 
     return true; 
    }  

    // Convenience method 
    public static bool IsImage(byte[] data) 
    { 
     return Images.Any(detector => detector.Matches(data)); 
    }   
} 
+0

Pourquoi le downvote? –

+0

lol, pas encore une fois ... downvote enlevé en raison de votre modification. Compte tenu des nouvelles informations que l'auteur a ajouté maintenant, il serait préférable d'écrire correctement la méthode IsFileImage pour lui. Vous travaillez sur ça? Je ne perds pas mon temps si vous êtes ... – TheSoftwareJedi

+0

note, je n'ai pas vu qui a répondu de cette façon. Si je savais que c'était vous, j'aurais commenté et expliqué ce qu'il essayait de faire ... peut-être encore une downvote tho: P Je pensais que c'était une mauvaise réponse à l'origine - mais là encore, c'était une mauvaise question aussi. :) – TheSoftwareJedi

0

Etes-vous sûr de "????" est le résultat?

Quel est le résultat de:

(int)ascii[0] 
(int)ascii[1] 

D'autre part, ASCII pur est 0-127 que ...

1

Si vous écrit alors:

Console.WriteLine(ascii) 

Et attendu "FFD8" à imprimer, ce n'est pas comme ça que fonctionne GetString. Pour cela, vous devez:

string ascii = String.Format("{0:X02}{1:X02}", header[0], header[1]); 
+0

Il serait alors imprimer "3F3F" - le plus gros problème (IMO) est le fait qu'il est converti en texte –

+0

3F =? ouais pas trop utile – Joshua

1

J'ai écrit un codeur sur commande/décodeur codé octets 0-255 aux caractères unicode 0-255 et retour.

Ce n'était vraiment utile que pour utiliser des fonctions de chaîne sur quelque chose qui n'est pas réellement une chaîne.