2

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

例如,如果我有一个包含以下内容的文本文件:

你好(标签)那里(换行符)朋友

我想将其转换为数组:

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",但我想知道是否有内置的东西。

4

4 回答 4

2

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

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();

对于您的目的,这可能会足够快。您可以通过单次遍历字符串、逐个字符读取并复制到 a 来加快速度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());
于 2013-08-02T16:58:46.807 回答
1

如果要转义所有控制字符,则可以使用 Regex.Escape。

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();
于 2013-08-02T16:53:28.773 回答
0

如果您不介意它比手动解决方案慢一些,那么您可以使用 a 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 语句来转换字符。它易于编写和理解,而且效率更高。

于 2013-08-02T16:49:53.790 回答
0

在“y”数组中,“转义字符”将具有它们的实际值(0x09、0x0D 等),其中一个不可打印的字符作为“文本”。

当您编写 \t、\n、\r 等时,您可以编写 (char)0x09、(char)0x0D,这就是数据写入的内容。换句话说,“\t”字符不存在!

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

于 2013-08-02T16:53:49.133 回答