我需要将文本文件的字节数组转换为它的字符串字符表示形式。
例如,如果我的文本文件包含:
你好(tab)那里(换行)朋友
我想将其转换为数组:
my_array = {'h', 'e' ,'l','l','o', '\t', 't', 'h','e','r','e', '\r','\n', 'f', 'r' ,'i','e','n', 'd'};
我将控制字符转换为其转义字符串时遇到了问题,即:
- 0x09 =' \ t&#39 ;;
- 0x0D =' \ r';
- 0x0A =' \ n';
我试过这个,但标签和新行没有在这里表示:
byte[] text_bytes = File.ReadAllBytes("ok.txt");
char[] y = Encoding.ASCII.GetChars(text_bytes);
我知道我可以循环遍历每个字节并有条件查找0x09
如果找到它,然后替换为"\t"
,但我想知道是否有某些内容内置。
答案 0 :(得分: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();
这可能会足够快到达你的目的。您可以通过单次传递字符串,逐个字符地阅读并复制到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());
答案 1 :(得分: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();
答案 2 :(得分:0)
如果您不介意它比手动解决方案慢一点,那么您可以使用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语句来转换字符。它易于编写和理解,而且效率更高。
答案 3 :(得分:0)
在“y”数组中,“转义字符”的实际值(0x09,0x0D等)将带有不可打印的字符作为“文本”。
当你写\ t,\ n,\ r \ n等时,你可能写了(char)0x09,(char)0x0D这就是数据写入的内容。换句话说,“\ t”字符不存在!
无论你是自己动手还是使用现有的库,都会有人将0x09映射到“\ t”转义序列并将其注入你的字符串。