1

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

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

%n|sectionName

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

最后,最后一点背景是我对 iOS 编程相当陌生。

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

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

我在这里走死胡同吗?我应该寻求子类NSInputStream化,还是应该采取一些我错过的其他方法?

4

4 回答 4

3

NSCoding is probably the wrong approach. It's designed for serializing and unserializing Objective-C types, not parsing a custom file format.

There's probably no need to subclass NSInputStream either. Your best bet here is probably to use C's stdio library, in particular fgets to read the lines. If you really want to use NSInputStream or NSFileHandle you certainly can, you'll just have to parse out each line from the string yourself (which is really not that hard).

于 2011-04-10T02:38:18.727 回答
2

I recommend using Ragel to handle the parsing smarts. It should be much easier than using NSScanner once you have the basic scaffolding in place to set up the parser and feed bytes into it until parsing finishes.

What objects you want to use to store the parsed results in is up to you. It shouldn't be too hard to build your object graph using action functions triggered by state machine transitions.

How you want to get bytes to feed into Ragel is also up to you. You can use C standard IO streams, Foundation streams, or Foundation file handles. All Ragel cares about is getting its hands on a buffer of characters so it can run it through the state machine your description was compiled into.

NSCoder is likely to be more trouble than it's worth for your purposes. It expects to be used as a way to persist and decode an Obj-C object, with the coding/decoding driven by the object's demands ("Okay, now gimme an int, now a short, how's about an Obj-C object now…").

于 2011-04-11T16:18:11.367 回答
1

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

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

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

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

编辑

This preprocessing using another language is not possible on iOS devices AFAIK. So this option is only possible on the mac.

于 2011-04-05T19:58:14.860 回答
1

There are a few open source parsing related kits, each targeting slightly different purposes. One or none of this might be useful to you, but mentioning them in response to your question seems like it might be useful to others, at least.

于 2011-04-12T21:14:40.167 回答