为啥我用BinaryReader和BinaryWriter的方式读写一个二进制文件(如可运行的的exe)显示有时会出现乱码跟一些字符串?
更不明白的是,我先读一个可运行的二进制文件在listbox里面(有时出现乱码),然后再把listbox的内容写到另一个的exe文件,发现这个文件就不可运行了,怎样保证读出二进制文件(显示里面内容),然后再写回去结果还是可以运行的?

解决方案 »

  1.   

    还需要指定一直编码格式
    http://club.sm160.com/showtopic-639782.aspx
      

  2.   

    写文件:     using (FileStream fs = new FileStream(sfd.FileName,
                             FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
                        {
                            BinaryWriter bw = new BinaryWriter(fs);
                            byte[] byteArr = Encoding.Unicode.GetBytes(listBox1.Items.ToString());
                            for (int i = 0; i < byteArr.Length; i++)
                            {
                                bw.Write(byteArr[i]);
                            }
                            bw.Close();
                        }
                        //return;
    读文件:    using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
                        {
                            BinaryReader br = new BinaryReader(fs);
                            byte[] bytes = br.ReadBytes((int)fs.Length);
                            //a = BitConverter.ToInt32(b, 0);
                            for (int i = 0; i < bytes.Length; i++)
                            {                            if (listBox1.Items.IndexOf(bytes[i].ToString()) != -1)
                                    listBox1.Items.RemoveAt(listBox1.Items.IndexOf(bytes[i].ToString()));
                                listBox1.Items.Add(bytes[i].ToString());
                            }
                            br.Close();
                        }
                        //return;
      

  3.   

    处理二进制数据,不要直接和任何UI控件作交互,基本没有必要,谁看的懂呢,如果必须,需要转换一下二进制数据,例如转成16进制显示,或Base64
      

  4.   

    以16进制显示,或Base64,跟编码应该没关了吧
      

  5.   

    我只不过想把一个二进制文件读出来显示,然后能够把显示的内容重新保存到文件(内容,结果不变)就这么简单
    PS:如果以16进制显示,或Base64,跟编码应该没关了吧
      

  6.   

    二进制的内容就应该用16进制显示,这样才容易看懂,写回去同理。
    要16进制显示很简单,对每个byte调用ToString,然后拼接这些字串来显示(如果你高兴,可以写个类似的函数)。        public static string ByteToString(byte[] input)
            {
                StringBuilder sb = new StringBuilder();
                foreach (byte b in input)
                {
                    sb.Append(b.ToString("X2"));
                }
                return sb.ToString();
            }写回去的话就是反向操作,类似的。
      

  7.   

    话说貌似我3楼的方法就是ToString()
      

  8.   


    没有必要显示二进制内容,这根本不是一个正常需求,因为没有人可以直接看懂二进制
    16进制或Base64只是显示格式的不同,不涉及编码问题。
    16进制或Base64可以确保显示的二进制绝对可读,不会出现乱码,而且回写后他们的数据保持和以前一致。
      

  9.   

    这是反向操作的代码,你用Encoding.Unicode.GetBytes显然是错误的。        public static byte[] StringToBytes(string input)
            {
                int len = input.Length;
                if (len % 2 != 0)
                {
                    throw new Exception("输入的字符串长度有误,必须是偶数。");
                }
                byte[] bytes = new byte[len / 2];
                for (int i = 0; i < len / 2; i++)
                {
                    if (!byte.TryParse(input.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber, null, out bytes[i]))
                    {
                        throw new Exception(string.Format("在位置{0}处的字符无法转换为16进制字节", i * 2 + 1));
                    }
                }
                return bytes;
            }
      

  10.   

    我把我的方法改成16进制的,还是出现乱码啊
    你的方法是把整个文件转换成一个string显示,我是根据文件的每一个字符(按照你改成16进制)显示
      

  11.   

    如图所示:代码如下:  using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
                        {
                            BinaryReader br = new BinaryReader(fs);
                            byte[] bytes = br.ReadBytes((int)fs.Length);
      
                         
                           listBox2.Items.Add(ByteToString(bytes));
                            br.Close();
                        }
      

  12.   

    你的二进制文件读取后不能进行任何编码转换,而是直接将byte【】转换为0x或base64显示即可以base64为例,将文件byte【】转换为base64,Convert类中这个功能,显示在UI上
    然后从UI读取base64串,再转换回byte【】,Convert类中这个功能,写入文件肯定没错。
      

  13.   

    建议你看看ASCII是什么。。看看system。text。Encoding namespace
      

  14.   

    你的代码为啥不行我没仔细研究,只给你改下,肯定行:
    using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
    {
        byte[] bytes = new byte[fs.Length];
        fs.Read(bytes, 0, bytes.Length);
        listBox2.Items.Add(ByteToString(bytes));
    }
      

  15.   

    另外转换效率问题,我给的是基本方法,效率并不高,如果自己改写那个ToString和byte.TryParse方法,可以提高10倍的速度,如果换到指针操作,速度还可以提高。