【问题标题】:Need help using Read7BitEncodedInt需要帮助使用 Read7BitEncodedInt
【发布时间】:2011-06-11 23:57:08
【问题描述】:

我一直在寻找 2 小时或更长时间来寻找一种为此使用 Read7BitEncodedInt 方法的方法。我需要以某种方式使用它来减小我的文件大小(在这种情况下可能减少 100mb 或更多)。我也在考虑使用 ReadString 方法,因为它似乎做了大致相同的事情。但这似乎不太合适,我不确定它是否会起作用。如果还有其他我不知道的替代方法,我也愿意使用它。

总之。我将如何将 Read7BitEncodedInt 方法实现到以下代码中? 另外,我也不太确定我的 Write7BitEncodedInt 方法是否正确。

    public void SaveFile()
    {
        using (FileStream stream = new FileStream("C:\\A_random.txt", FileMode.Create))
        {
            using (BinaryWriter writer = new BinaryWriter(stream))
            {
                for (int i = 0; i < typeCount.Count; i++)
                {
                    writer.Write((byte)typeCount[i]);
                    writer.Write(type[i]);
                }
                writer.Close();
            }
        }
        LoadFile();
    }

    public void LoadFile()
    {
        using (FileStream stream = new FileStream("C:\\A_random.txt", FileMode.Open))
        {
            using (BinaryReader reader = new BinaryReader(stream))
            {
                int i = 0;
                while (stream.Position != stream.Length)
                {
                    int count = reader.Read7BitEncodedInt();
                    byte val = reader.ReadByte();
                    for (int ii = 0; ii < count; ii++)
                    {
                        grid[i].val1 = i;
                        grid[i].val2 = val;
                        grid[i].val3 = vect;
                        i++;
                    }
                }
                reader.Close();
            }
        }
    }

【问题讨论】:

  • 如果我理解正确,您想使用 7bitencodedint 方法来减小文件大小。所以你需要更新你的 SaveFile 方法以利用 write7bitencodedint 方法,并确保你的 loadfile 方法可以读回它?
  • @Brian Dishaw Ya 总结得差不多了。
  • 我找到了一篇文章,它解释了为什么它们是受保护的方法以及如何在自己的代码中实现它们。我不确定这有多过时。我建议将程序集加载到 .net 反射器之类的东西中,并查看这些方法的实现。 dotnet247.com/247reference/msgs/53/268025.aspx
  • 您能解释一下您认为这样做可以减少文件大小吗?因为我对 7 位编码的理解是它至少增加了 14% 的文件大小。 7 位编码的目的是为了与非常旧的数据传输系统兼容,这些系统期望每个字节的最高位都关闭。它解压缩整数,而不压缩它们。如果需要的话,为什么不使用标准压缩库来压缩文件?
  • @Eric,该方法使用的编码与Protocol Buffers' varints基本相同。它减少了小整数的大小,而大整数最多可以占用 5 个字节。

标签: c# .net binary binarywriter 7-bit


【解决方案1】:

这是一种方法:

public class MyBinaryReader : BinaryReader {
    public MyBinaryReader(Stream stream) : base(stream) {}
    public new int Read7BitEncodedInt() {
        return base.Read7BitEncodedInt();
    }
}

public class MyBinaryWriter : BinaryWriter {
    public MyBinaryWriter(Stream stream) : base(stream) {}
    public new void Write7BitEncodedInt(int i) {
        base.Write7BitEncodedInt(i);
    }
}

还有一些测试代码:

void Main() {
var stream = new MemoryStream();

var writer = new MyBinaryWriter(stream);    

writer.Write7BitEncodedInt(100);
writer.Write7BitEncodedInt(1000);
writer.Write7BitEncodedInt(10000);
writer.Write7BitEncodedInt(100000);
writer.Write7BitEncodedInt(1000000);
writer.Write7BitEncodedInt(-1000000);

stream.Position = 0;

var reader = new MyBinaryReader(stream);    

Debug.Assert(reader.Read7BitEncodedInt() == 100);
Debug.Assert(reader.Read7BitEncodedInt() == 1000);
Debug.Assert(reader.Read7BitEncodedInt() == 10000);
Debug.Assert(reader.Read7BitEncodedInt() == 100000);
Debug.Assert(reader.Read7BitEncodedInt() == 1000000);
Debug.Assert(reader.Read7BitEncodedInt() == -1000000);
}

【讨论】:

  • 非常酷。它似乎工作得非常好,绝对比我正在做的要干净得多。谢谢:)
【解决方案2】:

在这种情况下,您在提出问题之前已经想到了问题的解决方案,即使该解决方案是一个坏主意。在 Raymond Chen's blogEric Lippert's blog 或两者都有关于这个主题的博客条目,但我找不到(他们)。

在过去的 20 年中,需要关心 7 位字符已基本被淘汰。而且,试图通过使用它们来节省磁盘空间的想法显然是荒谬的。

唯一可行的方法是重叠字符,以便有效地将 8 个字符组合成 7 个字节。我几乎可以不用看就可以保证Read7BitEncodedInt 不是这样做的。

(其实我也不知道它是做什么的,还好我不在乎)

如果您需要处理大文件,请使用某种压缩。 Zip、GZip、7-Zip 等等。

编辑:由于您实际上并没有询问字符串,因此这可能有用。然而,YMMV。查找ReadVLIWriteVLI 函数。

http://gilgamesh.hamsterrepublic.com/websvn/filedetails.php?repname=ohrrpgce&path=%2Fwip%2Freload.bas&rev=3568&peg=4164

【讨论】:

  • 这是一个非常糟糕的做法,因为现在高清空间很便宜,您有权在其他人的机器上随意使用您想要的任何东西。通过这种手动压缩,我的文件大小平均从 380MB 减少到了 35MB。毕竟显然不是过时的做法。你的和 Hans Passant 的 cmets 都近乎垃圾邮件。如果不是最后一分钟的 cmets 关于 Zipping 他们会。如果您不具有建设性,请不要发表评论。由于您似乎不知道这一点,因此有问题的方法根据需要将 Int 转换为 1-4 个字节。
  • @Grimbly,那是不可能的。它将其转换为 1 到 5 个字节。
  • @Grimbly,啊,看,你将 二进制 数据放入一个以 .txt 结尾的文件这一事实让我感到震惊。我以为你在谈论字符串。我自己编写了代码来执行此可变长度编码,我将添加到我的答案的链接。
  • 是的,.txt 现在只是一个简单的占位符。它最终可能最终成为自定义扩展。我试图压缩的 Ints 在我的测试中通常是单个数字,因此它们压缩到单个字节。最终结果很可能是那些大部分减少到 2 个字节的字节,其中大约有 5000 万字节,这似乎值得做。如果有人好奇的话,有问题的 Int 代表后面字节的迭代。我现在实际上已经完成了这项工作,但不想回答我自己的问题,我希望你的答案会表现得更好。也感谢您的链接。
猜你喜欢
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2020-08-26
  • 2015-05-20
  • 1970-01-01
相关资源
最近更新 更多