【问题标题】:C# binary writing return bigger fileC#二进制写入返回更大的文件
【发布时间】:2013-04-21 09:55:39
【问题描述】:

我在二进制写入器问题上遇到了一点麻烦,我的程序设置为加载 SHIFT-JIS 字符,并以相同的编码写入,但它返回一个更大的文件:s 尽管我删除了几个字符,@987654321 @,这些是打开和保存代码:

private void Openbtn_Click(object sender, EventArgs e)
    {
        listView1.Items.Clear();
        textBox1.Text = "";
        menuItem12.Text = "file type is: ";
        OpenFileDialog ofd = new OpenFileDialog();
        ofd.Title = "Open File";
        ofd.Filter = "All Files (*.*)|*.*";
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            menuItem13.Enabled = true;
            menuItem14.Enabled = true;
            menuItem15.Enabled = true;
            path = ofd.FileName;
            BinaryReader br = new BinaryReader(File.OpenRead(path), Encoding.GetEncoding("SHIFT-JIS"));
            foreach (char mychar in br.ReadChars(4)) menuItem12.Text += mychar;
            if (menuItem12.Text != "file type is: TXTD")
            {
                MessageBox.Show("This is not a TXTD file...", "Sorry", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else
            {
                    MessageBox.Show("File opened Succesfully!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    br.BaseStream.Position = 0x8;
                    int Pntrnum = br.ReadInt16();
                    menuItem11.Visible = true;
                    menuItem11.Text = Pntrnum.ToString();
                    List<int> offsets = new List<int>();
                    br.BaseStream.Position = 0x10;
                    for (int i = 0; i < Pntrnum; i++)
                    {
                        offsets.Add(br.ReadInt32());
                    }
                    Dictionary<int, string> values = new Dictionary<int, string>();
                    for (int i = 0; i < offsets.Count; i++)
                    {
                        int currentOffset = offsets[i];

                        int nextOffset = (i + 1) < offsets.Count ? offsets[i + 1] : (int)br.BaseStream.Length;

                        int stringLength = (nextOffset - currentOffset - 1);

                        br.BaseStream.Position = currentOffset;

                        var chars = br.ReadChars(stringLength);
                        values.Add(currentOffset, new String(chars));
                    }

                    foreach (int offset in offsets)
                    {
                        listView1.Items.Add(offset.ToString("X")).SubItems.Add(values[offset]);
                    }

                    br.Close();
                    br = null;
            }
        }
        ofd.Dispose();
        ofd = null;
    }
private void Savebtn_Click(object sender, EventArgs e)
    {
        BinaryWriter bw = new BinaryWriter(File.OpenWrite(path));

        int number_pointers = Convert.ToInt32(menuItem11.Text);

        Encoding enc = Encoding.GetEncoding("SHIFT-JIS");

        bw.BaseStream.Position = 0x10;
        int curr_pointer = 16 + number_pointers * 4;

        //pointers writing
        for (int i = 0; i < number_pointers; i++)
        {
            bw.Write(curr_pointer);
            curr_pointer += enc.GetByteCount(listView1.Items[i].SubItems[1].Text) + '\0';
        }

        for (int i = 0; i < number_pointers; i++)
        {
            bw.Write(enc.GetBytes(listView1.Items[i].SubItems[1].Text + '\0'));
        }

        bw.Flush();
        bw.Close();
        bw = null;
    }

非常感谢您的帮助。

【问题讨论】:

  • 我不太明白 open 函数可能对文件大小有什么影响,如果那是改变它,那么该函数做错了什么。否则 menuItem1 总是一样的吗?跨度>
  • menuitem1 是 openbtn,我只是重命名了它,所以你们可以说哪个是哪个,另外,我想我可能在 open 函数中做错了什么,这就像将日本字符读取为 UTF 或东西,示例文件在您的服务下,先生。
  • 我建议您将保存功能复制到控制台应用程序中,并将.text 值更改为可能的示例有效项目,我不喜欢单击文件链接,抱歉。编辑:我也用 Shift-JIS 做了很多工作,我相信你知道这是一个加密的噩梦,如果可能的话,我还是会使用 UTF-8,因为它支持地狱更多
  • 我理解这种担忧,但我不是那些在网络上传播病毒的顽固互联网用户之一,我真的很认真,我已经尝试解决这个问题超过 4 天了:/跨度>
  • 那么忽略文件大小,实际显示的文本在保存和加载后看起来是否相同?

标签: c# winforms listview binarywriter


【解决方案1】:

查看您提供的 Samples.zip 中的“After”文件似乎表明您正在输出相同的字符串两次,或者其他什么...

我建议您从较小的文件开始进行测试,并使用调试器介入。

实际上,在我自己尝试过之后,我想我发现了发生了什么:您使用“nextOffset - currentOffset”作为 stringLength,但它实际上是一个 BYTE-Length ... char 数组将结束(有一个'\0' inside)只在这个数字的一​​半之后,输出时你还会得到你还没有读过的后半部分。

[编辑] 从我的评论中发布代码,以获得更好的格式:

int index;
for (index = 0; index < stringLength; ++index) if (chars[index] == '\0') break;
if (index < stringLength) {
    char[] relevantPart = new char[index];
    Array.Copy(chars, relevantPart, index);
    chars = relevantPart;
}

【讨论】:

  • 有没有我可以将长度设置为它遇到 0x00 的位置?
  • 当然,但是你需要一个新的数组来只保存相关的字符......比如:int index; for (index = 0; index
  • 谢谢,但它仍然给我一个错误:Array.Copy 行上没有重载方法 'copy' 需要 4 个参数:/
  • 糟糕,我没有测试这部分代码(这就是我说“类似”的原因)...使用 Array.Copy(chars, relatedPart, index); 代替(如答案所示)。这次我测试了一下。 :D
  • 没有“chars”,只有“Char”和“char”...您的原始变量,“var chars = br.ReadChars(stringLength);”很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 2018-03-20
相关资源
最近更新 更多