c#十六进制字节0x09(ascii->tab)到“; 〃;一串

本文关键字:tab 一串 字节 十六进制 0x09 ascii- | 更新日期: 2023-09-27 18:25:55

我需要将文本文件的字节数组转换为字符串表示。

例如,如果我有一个文本文件,其中包含:

你好(标签)有(换行)朋友

我想把它转换成一个数组:

my_array  = {'h', 'e' ,'l','l','o', ''t', 't', 'h','e','r','e', ''r',''n', 'f', 'r' ,'i','e','n', 'd'};

我在将控制字符转换为转义字符串时遇到了问题,例如:

  • 0x09="''t"
  • 0x0D='''r'
  • 0x0A="''n"

我试过了,但标签和新行在这里没有显示:

byte[] text_bytes = File.ReadAllBytes("ok.txt");
char[] y = Encoding.ASCII.GetChars(text_bytes);

我知道我可以循环遍历每个字节,并有一个条件来查找0x09,如果我找到了它,然后用"'t"替换,但我想知道是否有内置的东西。

c#十六进制字节0x09(ascii->tab)到“;	〃;一串

有几种方法可以做到这一点。最简单的方法是将整个文件加载到内存中:

string theText = File.ReadAllText(filename);

然后使用string.Replace替换您感兴趣的项目:

// "escaping" the ''t' with '''t' makes it write the literal characters ''' and 't'
theText = theText.Replace("'t", "''t");
theText = theText.Replace("'r", "''r");
theText = theText.Replace("'n", "''n");

然后您可以创建您的字符数组。如果你确定它都是ASCII文本,你可以使用Encoding.ASCII:

byte[] theChars = Encoding.ASCII.GetBytes(theText);

或者,如果你想要一个字符数组:

char[] theChars = theText.ToCharArray();

这可能对你的目的来说已经足够快了。您可以通过对字符串进行一次遍历、逐个字符读取并复制到StringBuilder:来加快速度

StringBuilder sb = new StringBuilder(theText.Length);
foreach (char c in theText)
{
    switch (c)
    {
        case ''t' : sb.Append("''t"); break;
        case ''r' : sb.Append("''r"); break;
        case ''n' : sb.Append("''n"); break;
        default : sb.Append(c); break;
    }
}
byte[] theChars = Encoding.ASCII.GetBytes(sb.ToString());

如果您想转义所有控制字符,那么您可以使用Regex.Eescape.

string myText = File.ReadAllLines("ok.txt");
//to optimize, you could remove characters that you know won't be there (e.g. 'a)
Regex rx = new Regex(@"['a'e'f'n'r't'v]", RegexOptions.Compiled); 
myText = rx.Replace(myText, m =>  { return Regex.Escape(m.Value); });
Console.WriteLine(myText);

您不能以发布的方式将其转换为char数组,因为转义的控制字符将算作两个字符('t)。但如果你不介意每个角色都是分开的,你可以简单地进行

char[] myCharArray = myText.ToCharArray();

在"y"数组中,"转义字符"的实际值(0x09、0x0D等)将以一个不可打印的字符作为"文本"。

当您写入''t、''n、''r等时,您可以写入(char)0x09、(char)0x00D,这就是数据的写入方式。换句话说,"''t"字符不存在!

无论您是滚动自己的库,还是使用现有库,都必须有人将0x09映射到"''t"转义序列,并将其注入到您的字符串中。

如果您不介意它比手动解决方案慢一些,那么您可以使用CodeDomProvider(这可能足够快)。

我在这里找到了示例代码:http://code.google.com/p/nbehave-cf/source/browse/trunk/CustomTool/StringExtensions.cs?spec=svn5&r=5

using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
namespace CustomTool
{
    public static class StringExtensions
    {
        public static String ToLiteral(this String input)
        {
            using (var writer = new StringWriter())
            {
                using (var provider = CodeDomProvider.CreateProvider("CSharp"))
                {
                    provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
                    return writer.ToString();
                }
            }
        }
    }
}

您可以通过使用Encoding.Ascii.ReadString()读取字符串来使用它,然后使用.ToLiteral()将其转换为字符串,再使用.ToCharArray()来获得最终结果。

这给出了正确的结果,例如:

// You would do (using your sample code):
// string test = Encoding.ASCII.GetString(text_bytes);
string test = "hello'tthere'nfriend";
char[] result = test.ToLiteral().ToCharArray();

如果您检查result,您将看到它具有正确的字符。

不过,我只需要使用一个循环和一个switch语句来转换字符。它易于书写和理解,而且效率会高得多。