注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

面包会有的

php asp 高端网站开发 微信网站开发 视频会议软硬件

 
 
 

日志

 
 

多种输出字节数组的方法  

2017-02-10 22:48:53|  分类: C# |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
.NET(C#): 多种输出字节数组的方法
更新:
建议使用这篇文章描述的方法来输出字节数组!

跟计算机打交道难免经常需要输出一个字节数组。这篇文章就讲讲怎样输出一个字节数组在.NET下的各种方法:

最快捷方法:

string BitConverter.ToString(byte[])方法。(有重载支持字节数组的部分输出)

 

代码:
Console.WriteLine(BitConverter.ToString(new byte[] { 1, 3, 54, 123, 199, 200, 215, 255 }));
输出:
01-03-36-7B-C7-C8-D7-FF
 

缺点是无法自定义中间的间隔符(或者去掉中间的间隔符)。

如果需要修改(或去掉)间隔符的话,最简单的方法就是直接替换:

Console.WriteLine(BitConverter.ToString(new byte[] { 1, 13, 54 }).Replace("-", ""));
 

不过还是自己定义一个比较好:

//自定义输出字符数组方法
static string GetBytesString(byte[] bytes, int index, int count, string sep)
{
    var sb = new StringBuilder();
    for (int i = index; i < count - 1; i++)
    {
        sb.Append(bytes[i].ToString("X2") + sep);
    }
    sb.Append(bytes[index + count - 1].ToString("X2"));
    return sb.ToString();
}
 

上面这个GetBytesString方法看起来简单易懂了,当然还有其他方法使它更简洁,看看下面这个修改后的GetBytesString,用String.Join和LINQ,一句话搞定上面的代码:

//自定义输出字符数组方法(更简洁)
static string GetBytesString(byte[] bytes, int index, int count, string sep)
{
    return String.Join(sep, bytes.Skip(index).Take(count).Select(b => b.ToString("X2")));
}
 

上面提到了LINQ,那么就用纯LINQ来试试解决这个问题,看下面代码(有点可拍):

//自定义输出字符数组方法(纯LINQ。除了字符串连接,格式化,返回字符串,这些LINQ不可能做到的)
static string GetBytesString(byte[] bytes, int index, int count, string sep)
{
    return new string(bytes.Skip(index).Take(count - 1).Select(b => b.ToString("X2") + sep).SelectMany(i => i.ToCharArray()).Concat(bytes.Skip(index + count - 1).Take(1).SelectMany(b => b.ToString("X2").ToCharArray())).ToArray());
}
 

上面这些代码都可以正确输出结果,比如:
Console.WriteLine(GetBytesString(new byte[] { 34, 5, 1, 13, 54 }, 2, 3, " = "));
输出:
01 = 0D = 36
 

最后还可以通过继承.NET中的IFormatProvider和ICustomFormatter来自定义格式器来提供对字节数组的输出,通过格式字符串来指定间隔符,最后使用String.Format来定义自定义格式器,格式字符串从而将字节数组输出,代码:

/// <summary>
/// 自定义格式器
/// </summary>
class MyFormatter : IFormatProvider, ICustomFormatter
{
    public object GetFormat(Type formatterType)
    {
        if (formatterType == typeof(ICustomFormatter))
            return this;
        return null;
    }
    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        //判断是字节数组,并根据格式字符串来返回相应结果
        if (arg is byte[])
            return GetBytesString((byte[])arg, format);
        throw new NotSupportedException();
    }

    static string GetBytesString(byte[] bytes, string sep)
    {
        return String.Join(sep, bytes.Select(b => b.ToString("X2")));
    }

}

public class Program
{
    static void Main(string[] args)
    {
        var bytes = new byte[] { 34, 13, 43, 92, 222 };
        //使用String.Format来定义一个格式器(IFormatProvider)
        Console.WriteLine(String.Format(new MyFormatter(), "{0: =|= }\n{1:-}\n{2}", bytes, bytes, bytes));
    }
}
输出:

22 =|= 0D =|= 2B =|= 5C =|= DE
22-0D-2B-5C-DE
220D2B5CDE
结果都正确。

 

上述方法我没有测试过性能,当然某些方法性能一看就知道不怎么地(比如那个纯LINQ的,用字符串替换的可能也会稍慢些)。

不过从中我最大的感触就是.NET的灵活性真是无处不在啊,细细品味,蛮有趣的。
  评论这张
 
阅读(203)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017