Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 检查类型为“的文件”;NeXT/Apple typedstream“;第4版(NSArchiver)_Ios_Objective C_Macos_Nscoding_Nsarchiving - Fatal编程技术网

Ios 检查类型为“的文件”;NeXT/Apple typedstream“;第4版(NSArchiver)

Ios 检查类型为“的文件”;NeXT/Apple typedstream“;第4版(NSArchiver),ios,objective-c,macos,nscoding,nsarchiving,Ios,Objective C,Macos,Nscoding,Nsarchiving,对于数据恢复程序,我需要能够从NSArchiver编写的文件中提取值+类型,而无需访问苹果的CF/NS框架 OS Xfile命令报告以下文件: NeXT/Apple typedstream data, little endian, version 4, system 1000 有没有关于这些文件是如何编码的文档,或者有没有人想出可以解析它们的代码 以下是此类数据的一个示例(也是:): 这包含一个NSAttributed字符串。我有一些类似的例子,其中包含NSMutableAttributedS

对于数据恢复程序,我需要能够从NSArchiver编写的文件中提取值+类型,而无需访问苹果的CF/NS框架

OS X
file
命令报告以下文件:

NeXT/Apple typedstream data, little endian, version 4, system 1000
有没有关于这些文件是如何编码的文档,或者有没有人想出可以解析它们的代码

以下是此类数据的一个示例(也是:):

这包含一个NSAttributed字符串。我有一些类似的例子,其中包含NSMutableAttributedString等,但最终都解析为NSAttributedString,我希望得到文本。其余的我不在乎,但我需要知道它是否有效

我目前的解决方案是使用nsunachiver,并且假设我总是应该在其中找到一个nsattributed字符串,获取它的第一个元素并读取它的文本,然后从中重新创建一个存档,看看它是否与原始数据相同。如果我得到一个异常或另一个归档文件,我假设该归档文件已损坏或无效:

NSData *data = [[NSData alloc] initWithBytesNoCopy:dataPtr length:dataLen freeWhenDone:false];
NSUnarchiver *a = NULL;

// The algorithm simply assumes that the data contains a NSAttributedString, retrieves it,
// and then recreates the NSArchived version from it in order to tell its size.
@try {
    a = [[NSUnarchiver alloc] initForReadingWithData:data];
    NSAttributedString *s = [a decodeObject];

    // re-encode the string item so we can tell its length
    NSData *d = [NSArchiver archivedDataWithRootObject:s];
    if ([d isEqualTo:[data subdataWithRange:NSMakeRange(0,d.length)]]) {
        lenOut = (int) d.length;
        okay = true; // -> lenOut is valid, though textOut might still fail, see @catch below
        textOut = [s.string cStringUsingEncoding:NSUTF8StringEncoding];
    } else {
        // oops, we don't get back what we had as input, so let's better not consider this valid
    }
} @catch (NSException *e) {
    // data is invalid
}
但是,上述代码存在几个问题:

  • 这不是x平台。我也需要这个在Windows上工作
  • 一些损坏数据的示例会导致写入stderr或syslog的错误消息(不确定是哪个),例如:
    ***mmap(size=1844674407160811104)失败(error code=12)***错误:无法分配区域***在malloc\u error\u break中设置一个断点以进行调试
    (我提交了一份错误报告,报告以“无法修复”的形式关闭)
  • 没有任何东西可以保证NSUNACHIVER代码是100%防崩溃的。malloc错误就是一个例子。在某些情况下,我可能会遇到总线错误,这将是致命的。如果我有用于解析的自定义代码,我可以自己处理(并修复遇到的任何崩溃)。(更新:我刚刚发现一些无效数据,这些数据确实会使带有SIGSEGV的NSUNACHIVER崩溃。)
  • 因此,我需要自定义代码来解码这些类型的档案。我已经看了一些,但无法理解它使用的代码。显然,有长度字段和类型字段,类型显然在0x81到0x86之间。此外,前16个字节是标头,包括偏移量14-15处的系统代码(0x03E8=1000)


    我还想知道这些源代码是否存在于一些旧的下一个源代码中,或者在曾经存在的Windows版本中,但是我在哪里可以找到它们呢?(注意:我被引导到GNUstep源代码(“core.20131003.tar.bz2”),在其中我找到了它的nsunachiver源代码,但该代码显然是从1998年开始使用的,它使用自己的编码,不理解这种“流式”编码。)

    看一下Cocodron对
    NSArchiver
    nsunachiver
    的开源实现:


    它似乎是GNU Objective-C运行时的一部分,尽管它并不完全是运行时的东西(请参阅: )

    此文件可以实现这些功能:

    虽然我不知道该格式的任何文档,但您可以通过检查旧达尔文(或OpenStep)版本的公共源代码来找到您要查找的信息

    例如,在
    objc-1.tar.gz
    中的
    typedstream.m
    文件中查看
    typedstream
    的实现

    此源代码应该能够读/写
    typedstream
    。请确保在使用苹果的许可证时确认它。

    首先,请查看一些有趣的信息

    很可能,可以使用
    plutil
    工具将格式转换为更可读的格式。此工具也可用于windows(它随iTunes for windows提供)。但不确定它的许可证


    问题在于文件包含转换为二进制的对象实例。仅仅了解文件格式是不够的,还需要了解每种类型是如何存储的。

    这里的部分问题是Cocoa/NeXTSTEP/OPENSTEP中的每个类都知道如何存档自己。在每个类中都有一个initWithCoder:/encodeWithCoder:方法,其中有一个用于typedstream的部分和另一个用于键控归档的部分。键控归档更为现代,通常表示为XML plists。这些可以以二进制形式编码,但是,毫无疑问,这种二进制形式与typedstream归档不同。此外,还对它们进行了键控,这样就可以轻松地提取单个数据片段,而无需读取之前的所有数据。Typedstream归档文件不是这样工作的。它们是基于顺序的,这意味着每个对象中的每个元素都是一个接一个地写入的。首先是类名,然后是版本,然后是每个数据段。GNUstep从未实现这一点的原因是编码顺序几乎不可能被发现

    当您归档对象图的根对象时,它会对该对象调用encodeWithCoder:方法,该方法反过来对它包含的每个对象调用encodeWithCoder:方法,依此类推,直到归档整个对象图。当使用键控存档(NSKeyedArchiver)完成此操作时,将适当地构建存档并设置键控。当使用类型化流存档(NSArchiver)完成时,同样的递归也会发生,但每次对对象进行编码时,它只是将每个元素以开发人员当时认为合适的顺序转储到存档中


    我希望这个解释能澄清一点。你前面的路很难走。在GNUstep中避免这样做是有原因的。如果我们有,我们仍在努力解决这个问题。

    弗兰克·伊伦伯格根据1999年的typedstream.m源代码编写了一个名为
    MEUnarchiver
    的NSunachiver替代品:

    它已被扩展以支持原始源代码未知的新类型。它仍然依赖于ObjC运行时为所有s提供NSCoding解码器实现
    NSData *data = [[NSData alloc] initWithBytesNoCopy:dataPtr length:dataLen freeWhenDone:false];
    NSUnarchiver *a = NULL;
    
    // The algorithm simply assumes that the data contains a NSAttributedString, retrieves it,
    // and then recreates the NSArchived version from it in order to tell its size.
    @try {
        a = [[NSUnarchiver alloc] initForReadingWithData:data];
        NSAttributedString *s = [a decodeObject];
    
        // re-encode the string item so we can tell its length
        NSData *d = [NSArchiver archivedDataWithRootObject:s];
        if ([d isEqualTo:[data subdataWithRange:NSMakeRange(0,d.length)]]) {
            lenOut = (int) d.length;
            okay = true; // -> lenOut is valid, though textOut might still fail, see @catch below
            textOut = [s.string cStringUsingEncoding:NSUTF8StringEncoding];
        } else {
            // oops, we don't get back what we had as input, so let's better not consider this valid
        }
    } @catch (NSException *e) {
        // data is invalid
    }