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

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

我希望ASCII等于要FFD8(JPEG SOI标记)C#和Encoding.ASCII.GetString

相反,我得到 “????”

+0

你在哪里看到“????” ?...请注意,0xFFD8不可打印。 – 2009-05-31 14:48:19

+0

编辑添加下面提供的新信息的问题。我想你可能会问错误的问题?也许最好在问你真正的问题时提出一个全新的问题......“写一个函数来确定一个文件是否只是一个基于标题信息的图像” – TheSoftwareJedi 2009-05-31 18:46:33

回答

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") 
8

是的,这是因为ASCII只有7位 - 它没有定义高于127的任何值。编码通常将未知二进制值解码为'?' (尽管这可以使用DecoderFallback来改变)。我相信,在大多数西方系统中,我怀疑你实际上是想要Encoding.Default这是“操作系统的默认代码页”...... code page 1252

你期待什么角色?

编辑:按照接受的答案(我怀疑这个问题是在我添加了我的答案后编辑的;我不记得看到关于JPEG的任何内容),除非是真正的编码文本数据,否则不应该将二进制数据转换为文本。 JPEG数据是二进制数据 - 所以你应该检查实际字节与预期的字节。

任何时候如果使用“普通”文本编码(例如ASCII,UTF-8等)将任意二进制数据(如图像,音乐或视频)转换为文本,就有可能导致数据丢失。如果你将其转换为文本,使用Base64这是很好,安全。但是,如果您只是想将其与预期的二进制数据进行比较,则最好不要将其转换为文本。

编辑:好的,这里有一个类来帮助给定字节数组的图像检测方法。我没有把它定义为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? – 2009-05-31 18:30:45

+0

大声笑,不是这个再次... downvote由于您的编辑删除。鉴于作者现在添加的新信息 - 最好为他正确编写IsFileImage方法。你正在努力?我不是在浪费我的时间,如果你是... – TheSoftwareJedi 2009-05-31 18:44:33

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]); 
1

我曾经写道:编码的字节0-255到Unicode字符0-255,然后再返回一个自定义的编码器/解码器。

这对于在实际上不是字符串的东西上使用字符串函数只是非常有用。