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

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

Я ожидаю ASCII равным быть FFD8 (JPEG SOI маркер)C# и Encoding.ASCII.GetString

Вместо этого я получаю "????"

+0

Где вы видите "????" ? ... Обратите внимание, что 0xFFD8 не может быть распечатан. –

+0

Редактировать вопрос, добавив новую информацию, представленную ниже. Думаю, вы задали неправильный вопрос? Возможно, лучше всего задать совершенно новый вопрос, где вы задаете реальный вопрос ... «написать функцию, которая определяет, является ли файл изображением, основанным только на информации заголовка» – TheSoftwareJedi

ответ

11

В этом случае вам лучше сравнить байт-массивы, а не преобразовать их в строку.

Если вы должны преобразовать в строку, я предлагаю использовать кодировку Latin-1 aka ISO-8859-1 aka Code Page 28591, поскольку эта кодировка будет отображать все байты с шестнадцатеричными значениями в диапазоне 0-255 на Unicode-символ с одинаковым шестнадцатеричным значением - удобный для этого сценария. Любой из следующих получит эту кодировку:

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

Приветствия за предложения. Почему бы вам сравнить байт-массивы? – iasksillyquestions

+2

Потому что это двоичные данные. JPEG-файлы не являются текстовыми, поэтому их не следует преобразовывать в текст. –

8

Да, это потому, что ASCII только 7-бит - он не определяет значения выше 127. Кодировки обычно декодируют неизвестные двоичные значения до?? (хотя это можно изменить, используя DecoderFallback).

Если вы собираетесь упомянуть «расширенный ASCII», я подозреваю, что вы действительно хотите Encoding.Default, который является «кодовой страницей по умолчанию для операционной системы» ... code page 1252 на большинстве западных систем, я считаю.

Какие символы вы ожидали?

РЕДАКТИРОВАТЬ: В соответствии с принятым ответом (я подозреваю, что вопрос был отредактирован после того, как я добавил свой ответ, я не помню, чтобы вообще ничего не видел о JPEG), вы не должны преобразовывать двоичные данные в текст, если только это не закодированные текстовые данные , Данные JPEG: двоичные данные - поэтому вы должны проверять фактические байты относительно ожидаемых байтов.

Каждый раз, когда вы конвертируете произвольные двоичные данные (например, изображения, музыку или видео) в текст, используя «обычную» текстовую кодировку (например, ASCII, UTF-8 и т. Д.), Вы рискуете потеря данных. Если у вас есть, чтобы преобразовать его в текст, используйте Base64, который красив и безопасен. Однако, если вы просто хотите сравнить его с ожидаемыми двоичными данными, лучше не преобразовывать его в текст вообще.

EDIT: Хорошо, вот класс, помогающий методу обнаружения изображений для заданного массива байтов. Я не сделал это HTTP-специфическим; Я не совсем уверен, действительно ли вы должны получить InputStream, просто прочитайте его, а затем снова получите поток. Я уклонился от вопроса, придерживаясь байтовых массивов :)

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

Почему downvote? –

+0

lol, не это снова ... downvote удален из-за вашего редактирования. Учитывая новую информацию, добавленную автором, теперь лучше всего правильно написать метод IsFileImage для него. Вы работаете над этим? Я не трачу свое время, если вы ... – TheSoftwareJedi

+0

Заметьте, я не видел, кто ответил так. Если бы я знал, что это был ты, я бы прокомментировал и объяснил, что он пытался сделать ... может быть, все еще с понижением: P Я думал, что это был плохой ответ изначально, но опять же, это был плохой вопрос. :) – TheSoftwareJedi

0

Вы уверены, что "????" это результат?

Что является результатом:

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

С другой стороны, чисто ASCII только 0-127 ...

1

Если вы тогда писали:

Console.WriteLine(ascii) 

И ожидается «FFD8» для печати, это не так, как работает GetString. Для этого вам понадобятся:

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

Затем он напечатал «3F3F» - самая большая проблема (IMO) - это тот факт, что он преобразуется в текст на всех –

+0

3F =? так что да не слишком полезно – Joshua

1

я когда-то написал пользовательский кодер/декодер, закодированные байты 0-255 для Юникода символов 0-255 и обратно.

Это было действительно полезно для использования строковых функций над тем, что на самом деле не является строкой.

 Смежные вопросы

  • Нет связанных вопросов^_^