看不到过去的NULL终结者

时间:2014-06-17 16:13:17

标签: c# null .net-4.5 terminator

我一直在努力解决这个问题。我创建了一个实用程序,允许您打开.TXT文件。这些文本文件包含PCL(打印命令语言)。当我导入一个新文件时,它被\ 0(NULL终止符)截断。因为PCL文件在所有内容中随机包含图形图像,所以导入会在第一个位图图像处被截断,因为位图图像以NULL开头。

这是如下所示的确切问题:Displaying Raw Data From Image File Using TextBox or RichTextBox?

不幸的是,我不能评论这个帖子,因为我的声望很低(新手)(需要15个代表)。也无法粘贴屏幕截图(需要10个代表)。


以下是Notepad ++显示信息的方式:

enter image description here


以下是我的RichTextBox显示相同信息的方式:

enter image description here


这就是为什么这是一个问题(缩小):

enter image description here

栅格数据恰好位于我需要的两个数据部分(PCL)之间。栅格数据下面的所有信息都不会被拉入。


这是我尝试过的(注意:我使用的是自定义的RichTextBox,但这不应该影响任何事情,因为它只是一个带拖放功能的RichTextBox):

byte[] bytes = new byte[2048];
string data = System.Text.Encoding.ASCII.GetString(bytes);
dragDropRichTextBox1.Text = data.Replace("\0", @"1");

这只会导致一个2048号的链#" 1"没有任何文本文件的数据拉入的字符。非常感谢任何帮助。

无论我做什么,我都想保留目前的拖放功能:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PCL_Utility
{
    public class DragDropRichTextBox : RichTextBox
    {
        public DragDropRichTextBox()
        {
            this.AllowDrop = true;
            this.DragDrop += DragDropRichTextBox_DragDrop;
        }

        void DragDropRichTextBox_DragDrop(object sender, DragEventArgs e)
        {
            //string[] fileText = e.Data.GetData(DataFormats.FileDrop) as string[];
            string[] fileText = e.Data.GetData(DataFormats.FileDrop) as string[];

            if (fileText != null)
            {
                foreach (string name in fileText)
                {
                    try
                    {
                        this.AppendText(File.ReadAllText(name) + "\n -------- End of File -------- \n\n");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);  
                    }
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:4)

首先,您不需要ASCII编码。 ASCII是7位编码。任何具有高位设置的字符(即字符代码128到255)都被解码器转换成问号。因此,将二进制数据读取为ASCII会破坏您的数据。

其次,富文本框在底层使用Windows控件,该控件旨在使用以null结尾的字符串。因此,它会在第一次看到'\0'字符时截断文本。如果要在编辑控件中显示二进制数据,则需要修改要显示的文本。

你的"文字"文件实际上不是文本,因为它们包含二进制(即非人类可读)数据。最好的办法是打开文件并将整个内容作为二进制文件读入内存缓冲区。那就是:

byte[] fileBytes = File.ReadAllBytes("filename");

然后,如果要在文本控件中显示数据,则必须创建表示数据的字符串。我会建议像:

StringBuilder sb = new StringBuilder();
foreach (var b in fileBytes)
{
    // handle printable characters
    if (b >= 32 || b == 10 || b == 13 || b = 9) // lf, cr, tab
        sb.Append((char)b);
    else
    {
        // handle control characters
        switch (b)
        {
            case 0 : sb.Append("(nul)"); break;
            case 27 : sb.Append("(esc)"); break;
            // etc.
        }
    }
}

您可能希望构建一个查找表,其中包含要转换的每个值的字符串,而不是构建一个大的switch语句。字典可能是最好的。类似的东西:

private Dictionary<byte, string> Conversions = new Dictionary<byte, string>()
{
    {0, "(nul)"},
    {27, "(esc)"},
    // etc.
};

然后你的循环可以做到这一点:

foreach (var b in fileBytes)
{
    string s;
    if (Conversions.TryGetValue(b, out s))
    {
        sb.Append(s);
    }
    else
    {
        sb.Append((char)b);
    }
}

答案 1 :(得分:1)

而不是尝试将文件数据读入字符串,正如Jim Mischel回答的那样,它应该被读入字节数组并进行处理。

这是一个静态类,它将文件读入字节数组,并根据字典查找处理它。对于不可打印的ASCII字符和超过127的所有值,我已使用“\ 00”预填充字典。

    public static class BinaryFile
    {

        private static string[] __byteLookup = new string[256];

        static BinaryFile()
        {
            // Display printable ASCII characters as-is
            for (int i = 0x20; i < 0x7F; i++) { __byteLookup[i] = ((char)i).ToString(); }

            // Display non-printable ASCII characters as \{byte value}
            for (int i = 0; i < 0x20; i++) { __byteLookup[i] = "\\" + i.ToString();}
            for (int i = 0x7F; i <= 0xFF; i++) { __byteLookup[i] = "\\" + i.ToString(); }

            // Replace pre-populated values with custom values here if desired.
        }

        public static string ReadString(string filename)
        {
            byte[] fileBytes = System.IO.File.ReadAllBytes(filename);

            return String.Join("", (from i in fileBytes select __byteLookup[i]).ToArray());
        }
    }

修改,因为您要将其与自定义拖放代码一起使用,其用法应为:

   void DragDropRichTextBox_DragDrop(object sender, DragEventArgs e)
    {
        string[] fileText = e.Data.GetData(DataFormats.FileDrop) as string[];

        if (fileText != null)
        {
            foreach (string name in fileText)
            {
                try
                {
                    // Read each file using the helper class rather than File.ReadAllText
                    // then append the end-of-file line
                    this.AppendText(BinaryFile.ReadString("your_file_name.txt") 
                        + "\n -------- End of File -------- \n\n");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);  
                }
            }
        }
    }