阅读器遇到的第一问题就是中文编码,许多网站都使用中文编码,而silverlight并不支持,这是首先要解决的问题。
.NET Compact Framework同样也不支持GB2312编码,这个解决方法同样适用于.NET Compact Framework。
方法其实很简单,通过GB2312与unicode的对照表。首先把取得字节码,再转行到Unicode码,最后查表取得对应汉字,接下来就是实现的问题了。
首先定义转换字典:字典信息可以从 转换字典 获得。
第二步实现Encoding类,命名为:Gb2312Encoding,代码如下:
{
public override string WebName
{
get
{
return " gb2312 " ;
}
}
public Gb2312Encoding()
{
}
public override int GetBytes( char [] chars, int charIndex, int charCount, byte [] bytes, int byteIndex)
{
throw new NotImplementedException();
}
public override int GetChars( byte [] bytes, int byteIndex, int byteCount, char [] chars, int charIndex)
{
int j = 0 ;
char c;
for ( int i = 0 ; i < byteCount; i += 2 )
{
if (i + 1 >= bytes.Length)
{
char [] last = Encoding.UTF8.GetChars( new byte [] { bytes[i] });
chars[j] = last[ 0 ];
}
else
{
byte [] bb = new byte [] { bytes[i], bytes[i + 1 ] };
if (Gb2312toUnicodeDictinary.TryGetChar(bb, out c))
{
chars[j] = c;
j ++ ;
}
else
{
char [] tt = Encoding.UTF8.GetChars( new byte [] { bb[ 1 ] });
chars[j] = tt[ 0 ];
j ++ ;
// 测试下一个
if (i + 2 >= bytes.Length)
{
char [] tttt = Encoding.UTF8.GetChars( new byte [] { bb[ 0 ] });
chars[j] = tttt[ 0 ];
j ++ ;
}
else
{
byte [] test = new byte [] { bb[ 0 ], bytes[i + 2 ] };
if (Gb2312toUnicodeDictinary.TryGetChar(test, out c))
{
chars[j] = c;
j ++ ;
i ++ ;
}
else
{
char [] ttt = Encoding.UTF8.GetChars( new byte [] { bb[ 0 ] });
chars[j] = ttt[ 0 ];
j ++ ;
}
}
}
}
}
return chars.Length;
}
public override int GetByteCount( char [] chars, int index, int count)
{
return count;
}
public override int GetCharCount( byte [] bytes, int index, int count)
{
return count;
}
public override int GetMaxByteCount( int charCount)
{
return charCount;
}
public override int GetMaxCharCount( int byteCount)
{
return byteCount;
}
public static int CharacterCount
{
get { return 7426 ; }
}
}
最主要的是GetChars与GetBytes方法。两个方法是互逆的,一个编码一个解码。由于阅读器只用到了解码部分,这个类也只实现解码。编码和解码是一样的,只是逆向查表而已。
用到的可以自己实现。
使用方法:
wc.Encoding = new Gb2312Encoding();
wc.DownloadStringAsync( new Uri(Uri));
wc.DownloadStringCompleted += (s, args) =>
{
if (args.Error == null )
{
}
};
这样就可以得到Gb2312编码的网页内容了。
完整代码可以从下面的链接下载。
演示地址http://silverlightreader.limewebs.com/
代码http://htmlextractor.codeplex.com/
详细信息可以参考:http://blogs.msdn.com/b/feiyu/archive/2009/12/08/support-gb2312-in-silverlight-net-framework.aspx
接下来,silverlight 4的内存泄露问题与基于silverlight的欺骗服务器方法。
没想到silverlight4 会有如此严重的bug,模板的内存不会得到释放,由于阅读器用到EMF,并且所有控件都是动态加载到模板中的,内存会疯狂增长
silverlight在线阅读器(三):silverlight 4的内存泄露问题与基于silverlight的欺骗服务器方法