從輸出位元組數組品味.NET(C#)的靈活性

來源:互聯網
上載者:User

跟電腦打交道難免經常需要輸出一個位元組數組。這篇文章就講講怎樣輸出一個位元組數組在.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的靈活性真是無處不在啊,細細品味,蠻有趣的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.