【问题标题】:iOS custom file format loading with NSData & NSCoding使用 NSData 和 NSCoding 加载 iOS 自定义文件格式
【发布时间】:2011-07-30 06:42:43
【问题描述】:

我正在向一些 iOS Cocoa 程序员寻求一些指导,以了解如何实现一种机制来将自定义文件格式加载和解析到我将在内存中使用的模型对象中。我知道一定有很多方法可以解决这个问题,但让我分享一下我目前探索的路径的基本想法,以及我陷入困境的地方。

但首先,这里是上下文:假设我有一个无法更改的现有文件格式。它基本上是一种奇特的管道分隔格式,分为多个部分,每个部分的开头如下:

%n|sectionName

...以及随后的 n 行都以该部分独有的方式用竖线分隔。有些部分有一个以竖线分隔的标题行,后跟 n 行数据(也是以竖线分隔的),而其他部分可能只有 n 行以竖线分隔的行。文件开头有几个小部分,最后会有一个巨大的部分描述 k-ary 树的节点:它们的父子关系以及与每个节点关联的任何数据。总而言之,这些文件的大小为数十兆字节,未来可能会更大。

最后,最后一点是我对 iOS 编程还很陌生。

我首先使用NSFileHandle 来获取文件的表示形式作为NSData 的实例。这很容易,在探索NSData 接口并尝试从那里继续时,我注意到NSCoding 协议,它声称是一种将对象归档和序列化为(和从)表示形式的工具。

我认为这听起来像是我可能需要的东西,因为我倾向于认为文件格式只是我的模型对象可以编组到的表示形式。然而,在深入研究“档案和序列化编程指南”之后,我开始怀疑自己。 API 似乎不适合我想要完成的工作。

我是不是走上了死胡同?我应该寻求子类NSInputStream,还是应该采取一些我遗漏的其他方法?

【问题讨论】:

    标签: objective-c ios nsdata nscoding nsscanner


    【解决方案1】:

    有一些开源解析相关的工具包,每一个针对的目的略有不同。其中一项可能对您有用,也可能没有任何用处,但在回答您的问题时提及它们似乎至少对其他人有用。

    【讨论】:

      【解决方案2】:

      我建议使用Ragel 来处理解析智能。一旦你有了基本的脚手架来设置解析器并将字节输入其中直到解析完成,它应该比使用NSScanner 容易得多。

      您想使用哪些对象来存储解析结果取决于您自己。使用由状态机转换触发的动作函数来构建对象图应该不会太难。

      您希望如何获取字节以输入 Ragel 也取决于您。您可以使用 C 标准 IO 流、Foundation 流或 Foundation 文件句柄。 Ragel 所关心的只是获得一个字符缓冲区,以便它可以通过您的描述被编译到的状态机运行它。

      NSCoder 可能比您的目的更麻烦。它希望被用作持久化和解码 Obj-C 对象的一种方式,编码/解码由对象的需求驱动(“好吧,现在给我一个 int,现在给一个简短,现在 Obj-C 对象怎么样...... ")。

      【讨论】:

      • 感谢您对 Ragel 的指点。我会认真考虑将其作为一种选择。
      【解决方案3】:

      NSCoding 可能是错误的方法。它是为序列化和反序列化 Objective-C 类型而设计的,而不是解析自定义文件格式。

      也可能没有必要继承 NSInputStream。您最好的选择可能是使用 C 的 stdio 库,特别是 fgets 来阅读这些行。如果你真的想使用 NSInputStream 或 NSFileHandle 你当然可以,你只需要自己从字符串中解析出每一行(这真的不是那么难)。

      【讨论】:

      • 感谢您提醒我,我可以使用纯 C。我想我一直太专注于寻找合适的 Objective C 类来使用。巧合的是,昨天一个新的blog entry by BJ Homer 很好地解释了人们可能实际上想要继承 NSInputStream 的情况。我同意我的情况不符合条件。再次感谢您!
      【解决方案4】:

      正如您正确指出的那样,破解这个问题的方法不止一种。不幸的是,您没有指出您想对解析后的数据做什么以及最后是否要写出文件。

      首先,对于解析,必须考虑使用 Objective-C 是否有意义。我可以考虑编写一个非常适合解析文本文件并将输出写入 XML 文件或更好的 plist 文件的小型辅助 Perl 脚本。然后可以使用您的 Objective-C 代码读入这个文件,然后您就可以使用这些数据了。您还可以选择将数据写入 sqlite 数据库,这也是一种合适的文件格式,因为有适用于各种可用语言(C、Perl、Python 等)的数据连接器。

      其次,如果要解析文本文件,值得一看的类是NSLineScanner,它用于解析文本文件。

      我没有看到使用 NSInputStream 的任何好处,因为它只返回原始字节。

      编辑

      在 iOS 设备 AFAIK 上无法使用其他语言进行此预处理。所以这个选项只能在mac上使用。

      【讨论】:

      • 感谢您的回复。不幸的是,我无权通过预处理来更改格式。我可能不必把它写回去。至于我将如何处理数据:我将在内存中创建对象或结构(我自己设计的)的实例。之后发生的是导航、显示和可视化。我会将树结构保存在内存中,尽管与每个节点关联的数据可能是我可以在用户访问节点时按需加载的数据。
      • 好吧,预处理只是为了让你的生活更轻松,并实现一种私有的、易于使用的数据格式。你也可以在 Objective-C 中做任何事情,但是对于文本解析来说,perl 更强大,你可以将它与你的应用程序捆绑在一起,没有人会知道你在内部使用它。
      • iOS 中有 perl 解释器吗? perl 脚本会通过应用商店提交吗?
      • 啊,你找到我了。当然不是。我没有仔细阅读你的问题。所以你必须用 C、C++ 或 Objective-C 解析你的字符串。对不起。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 2020-09-05
      • 2021-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多