【问题标题】:C# Writing Binary DataC# 编写二进制数据
【发布时间】:2015-08-02 05:25:18
【问题描述】:

我正在尝试获取一些数据以写入二进制文件。数据由多个值(字符串、十进制、整数)组成,这些值需要是单个字符串,然后写入二进制文件。

到目前为止,我创建了文件,但它会将我的字符串在它们出现时放在那里,而不是将它们转换为二进制,当我在记事本中打开文件时,我认为它应该看起来像 1010001010 等?

实际输出是 Jesse23023130123456789.54321 而不是二进制数字。

我在哪里弄错了?

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

namespace BinaryData
{
    class Program
    {
        static void Main(string[] args)
        {
        string name = "Jesse";
        int courseNum = 230;
        int num = 23130;
        decimal d = 123456789.54321M;

        string combined = name + courseNum + num + d;

        FileStream writeStream;

        writeStream = new FileStream("BinaryData.dat", FileMode.Create);
        BinaryWriter bw = new BinaryWriter(writeStream);
        bw.Write(combined);
        }
    }
}

【问题讨论】:

  • 您希望将 0 和 1 写入文件?
  • 好的,但记事本显示文本。不是二进制的,所以,一个包含你写为位的文本的填充,仍然是文本..你只是一点一点地写它..@Shar1er80 为你找到了答案
  • 请注意,所有文本文件都是“二进制”文件,因为它们包含字节。某些文件被视为文本文件的事实只是一种约定,将字节解释为文本的决定。记事本遵循该约定,因此除非您将 text 1010101 写入文件,否则将打开二进制文件,就好像它包含文本一样。

标签: c#


【解决方案1】:

有不止一种方法可以做到这一点,但这里有一种基本方法。在将所有内容组合成一个 string 之后,遍历字符串并将每个字符转换为带有 Convert.ToString(char, 2) 的二进制表示。 ASCII 字符的长度通常为 7 位或更少,因此您需要 PadLeft(8, '0') 以确保每个字节 8 位。然后反过来,您只需一次抓取 8 位并将其转换回其 ASCII 字符。如果不使用前导 0 填充以确保 8 位,您将无法确定文件中每个字符由多少位组成。

using System;
using System.Text;

public class Program
{
    public static void Main()
    {
        string name = "Jesse";
        int courseNum = 230;
        int num = 23130;
        decimal d = 123456789.54321M;

        string combined = name + courseNum + num + d;

        // Translate ASCII to binary
        StringBuilder sb = new StringBuilder();
        foreach (char c in combined)
        {
            sb.Append(Convert.ToString(c, 2).PadLeft(8, '0'));
        }

        string binary = sb.ToString();
        Console.WriteLine(binary);

        // Translate binary to ASCII
        StringBuilder decodedBinary = new StringBuilder();
        for (int i = 0; i < binary.Length; i += 8) 
        {
            decodedBinary.Append(Convert.ToChar(Convert.ToByte(binary.Substring(i, 8), 2)));
        }
        Console.WriteLine(decodedBinary);
    }
}

结果:

01001010011001010111001101110011011001010011001000110011001100000011001000110011001100010011001100110000001100010011001000110011001101000011010100110110001101110011100000111001001011100011010100110100001100110011001000110001
Jesse23023130123456789.54321

Fiddle Demo

【讨论】:

  • ASCII?没有人要求 ASCII。 .NET 字符串和字符是 Unicode。试试“杰西欠我 20 欧元”。 (当然,问题没有指定编码,但答案中的代码没有检查其限制。)
  • @TomBlodget 点已被采纳。我假设 ASCII 带有问题中给出的示例数据,如果字符超出 ASCII 字符的范围,那么分隔符将不得不分隔每个字符的二进制。
  • 对我来说,样本数据包含一个人的姓名。那可能是Виктор Ан、안현수或Victor An。 (顺便说一句,都是同一个人。)
  • @TomBlodget 再次,我明白你的意思。我的回答没有考虑非 ASCII 字符,但正如你所说,问题没有指定编码。
【解决方案2】:

给你:

主要方法:

static void Main(string[] args)
        {
            string name = "Jesse";
            int courseNum = 230;
            int num = 23130;
            decimal d = 123456789.54321M;

            string combined = name + courseNum + num + d;
            string bitString = GetBits(combined);
            System.IO.File.WriteAllText(@"your_full_path_with_exiting_text_file", bitString);
            Console.ReadLine();
        }

该方法当然会根据您的字符串输入返回位 0 和 1:

   public static string GetBits(string input)
    {
        StringBuilder sb = new StringBuilder();
        foreach (byte b in Encoding.Unicode.GetBytes(input))
        {
            sb.Append(Convert.ToString(b, 2));
        }
        return sb.ToString();
    }

如果您想创建 .txt 文件,请为其添加代码。这个例子已经创建了一个 .txt,所以它只需要写入它的完整路径。

【讨论】:

  • 请记住,如果您决定重新读取该数据,您将不知道每个字符有多少位。
  • 顺便说一句:Encoding.Unicode.GetBytes 将为每个字符返回 2 个字节。所以对于ab,它会返回97,0,98,0,而你的for循环会在结果中附加不必要的0。一个糟糕的答案。
  • @EZI Encoding.Unicode.GetBytes(UTF-16 编码)将返回每个字符 2 或 4 个字节。
猜你喜欢
  • 2011-12-08
  • 1970-01-01
  • 2013-06-09
  • 2017-06-05
  • 2013-10-14
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
  • 2014-01-24
相关资源
最近更新 更多