【问题标题】:How should I save my data?我应该如何保存我的数据?
【发布时间】:2011-01-05 13:48:36
【问题描述】:

我有两个这样的结构:

public struct KeyLog
{
    Keys key;
    DateTime time;
}

public struct MouseLog
{
    MouseEvents mouse;
    Point coordinates;
    DateTime time;
}

对于每个键盘按键和鼠标按钮单击,我希望保存这些数据,但我不知道哪种方式最有效地存储/处理它?有没有更好的方法来处理数据 - 我不确定使用两个结构是否比将两者合并为一个更好?

编辑:我正在做一个键盘和鼠标统计应用程序,它将存储按键和鼠标点击的数量以及按下的按钮、我和我的计算机的位置和时间每次按下按钮时都希望保存此数据。不一定每次都写入磁盘,但至少将其存储在内存中,直到我想将其保存到磁盘。

编辑: 我认为如果我将这两个结构分开,我在存储它们时不会创建太多死数据,然后如果我将它们分开,我可以轻松搜索/排序。想法?

【问题讨论】:

  • 我假设您的应用程序中的字段是公开的?
  • 您想将此数据保存到哪里?一个文本文件,一个数据库?
  • 你说的保存是什么意思,你是说写入磁盘
  • 您的问题是您是否需要 2 个结构?这真的取决于!你想做什么?
  • 我想将它们保存到磁盘。我也在问这两个结构。阅读编辑以供应用程序使用。

标签: c# serialization information-retrieval


【解决方案1】:

我经常将它按顺序保存到具有非常简单的数据访问层的二进制文件中。您可以在这里使用几种方法,但我最喜欢这种方法,它相当简单而且速度很快。您甚至可以非常轻松地为文件中的条目创建索引表。

class Foo {
  private int _someInteger;
  private string _someString;

  public virtual void Serialize(BinaryWriter writer) {
    writer.Write(2); // A simple versioning, start at 0, then increment.
    writer.Write(_someString);
    writer.Write(_someInteger);
  }

  public virtual void Deserialize(BinaryReader reader) {
    int version = reader.ReadInt32();
    switch (version) {
      case 2: // the string was only added in version 2 of the class serialization.
        _someString = reader.ReadString(); 
        goto case 1;
      case 1: // continue at case 1.
        _someInteger = reader.ReadInt32();
        break; // break here, because version 0 was very different.
      case 0: // in version 0 of the class there was actually a double, but it was always an integral number, so this basically is a conversion case.
        _someInteger = (int)reader.ReadDouble();
        break;
    }
  }
}

请注意按照与写入它们相同的顺序从文件中读取它们。

然后您可以将它传递给流中的读取器和写入器,例如

Foo fooInstance = new Foo();
FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(fileStream);

fooInstance.Deserialize(reader);

它非常简单,您不必为愚蠢的 XML 序列化程序类暴露所有的字段和属性,而这总是会给您带来问题。

【讨论】:

    【解决方案2】:

    我会将它存储在一个结构中,因为它很可能会节省您作为程序员的时间。处理起来会更简单,尤其是在以后保存/加载文件时。使用您所描述的结构几乎没有什么收获。

    如果这应该成为性能问题,请分析代码以查看任何瓶颈所在,然后修复它们。

    【讨论】:

      【解决方案3】:

      合并它们将使它们易于编程..

      但是因为您更注重节省磁盘空间

      您可以使用 MouseLog 和 Keylog 的通用集合

      例如列表 内存表示列表

      因为要将其写入磁盘,您可以将它们放在一个类中并将它们保存为一个大对象

      喜欢

        [serializable]
          class BigObject 
          {
      
          List<Mouselog> MouseLogLst;
      
      
          List<KeyLog>  KeyLogLst ;
      
          }
      

      并使用Binary Formmater 存储它们

      【讨论】:

        【解决方案4】:

        您需要担心 Unicode 还是 ASCII?我会说 XML 是你的朋友。不要将两者合并,而是创建两个类,它们都是抽象 EventLog 的子项。 EventLog 类必须强制你使用 toString() 方法,也许还有其他一些方法。然后有一个 EventLog 列表,其中每个 EventLog 是 KeyLog 或 MouseLog。我想知道你是不是在重新发明轮子……

        【讨论】:

        • XML 不会使用不必要的空间吗?我想要存储的信息并不多,但我今天已经按下了超过 25k 键和 5k 鼠标点击,这将占用大量空间,如果我使用 XML,认为这是正确的术语吗?
        • 好的,然后使用简单的 ASCII 格式:[YYMMDDhhmmss FF][YYMMDDhhmmss 123,254 R][YYMMDDhhmmss 123,254 L][YYMMDDhhmmss 124,256][YYMMDDhhmmss 45] - 这里 FF, 45 是按键的十六进制表示(假设 ASCII)。不过,我还是建议使用类。写出来应该很容易。解析 - 也没有那么难。
        【解决方案5】:

        BinaryFormatter 会给你最小的压缩。此外,如果您将它们更改为类,您可以拥有一个带有 DateTime time 字段的基类。

        【讨论】:

          【解决方案6】:

          er.... 哪里你打算把它存储?如果您只是想要一个可以参考的内存日志,List&lt;X&gt; 应该没问题。

          如果要将其流式传输到磁盘,则需要对其进行序列化。就总磁盘空间而言,二进制序列化是最有效的,但 XML 序列化是“人类可读的”。

          然后是数据库存储...

          【讨论】:

            【解决方案7】:

            除非有充分的理由将它们分开,否则您应该合并它们。我相信 KISS 在这里适用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-11-11
              • 1970-01-01
              • 2011-11-05
              • 1970-01-01
              • 2022-08-15
              • 2018-02-03
              相关资源
              最近更新 更多