objective-c – 以用户的XML保存文件结尾的奇怪数据

我的应用程序使用 XML将用户数据保存到文件中.我刚刚收到了来自用户的2份报告,他们在文件中看到了完全意外的数据.而不是XML,它看起来像这样:

({"windows":[{"tabs":[{"entries":[{"url":"https://mail.google.com/a/cast...

还有一些来自文件中间的内容,重量接近30KB:

{\"n\":\"bc\",\"a\":[null]},{\"n\":\"p\",\"a\":[\"ghead\",\"\",0]},{\"n\":\"ph\",\"a\":[{\"gb_1\":\"http://www.google.com/

任何人都可以告诉我这是什么类型的数据,或者它是如何在我的用户的数据文件中结束的?两位用户都报告说必须按住电源按钮才能关闭他们的机器.一个案例中的关闭是Firefox冻结,另一个案例是鼠标问题.其中一个用户实际上遇到了内核恐慌.

我还不相信这是一个内存管理问题,因为我的用户群超过10万人,而且我只收到了2份报告.我认为它更窄/更罕见.

这是我用来将数据写入文件的代码片段:

NSString *xmlString = [[self convertContextToXmlString:context] retain];

NSError *e = nil;

[[xmlString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:location options:NSDataWritingAtomic error:&e];
[xmlString release];
if (e) {
    NSLog(@"An error occurred saving: %@",[e description]);
}
return e;

永远不会在后台线程上发生数据保存,总是在UI线程上.此外,我正在使用NSDataWritingAtomic选项将数据写入文件.

编辑:第二个用户的文件具有几乎相同的数据.所以两个错误的内容来自同一个地方,但在哪里?一旦我能够,我就会在这个问题上加上200分的赏金.

AV/////wEAAAAAAAAAAAABAAA="}]}]},{"url":"http://googleads.g.doubleclick.net/pagead/ads?client=ca-pu

编辑2:在按住电源按钮关闭机器后,收到来自也遇到数据损坏的用户的第三个报告.他的数据在开始时有很多随机垃圾,然后在最后有适当的数据:

(garbage)rred="1"><rest of it was normal xml...>

解决方法

从Apple开发者那里得到了一个很好的答案.将在未来几周内将我现有的模型移植到Core Data. (StackOverflow混淆了一些列表/格式,但它在很大程度上仍然非常易读.)

我将开始回答一个关于HFS Plus日记的问题.自从在Mac OS X 10.2.x中引入日志记录以来,Mac OS X的文件系统正确性保证一直是 – 无论内核恐慌,电源故障等等 – 文件系统操作将导致以下两种结果之一:

o操作将由期刊前滚,在这种情况下,操作就好像操作已成功完成

o或者操作将被回滚,就好像操作从未发生过一样

此保证有两个关键限制:

o它适用于单个文件系统操作(创建,删除,移动等),而不适用于操作组.

o它仅适用于逻辑文件系统结构,不适用于文件中的数据.

简而言之,该期刊的目的是防止整个文件系统损坏,而不是特定文件的损坏.

记住这一点,让我们来看看 – [NSData writeToFile:options:error:]的行为.它的行为可能非常复杂,但在典型情况下非常简单.探索此问题的一种方法是编写一些代码并使用它来查看其文件系统行为.例如,这里有一些测试代码:

- (IBAction)testAction:(id)sender
{

BOOL success;
NSData * d;
struct stat sb;

d = [@"Hello Cruel World!" dataUsingEncoding:NSUTF8StringEncoding];
assert(d != nil);

(void) stat("/foo",&sb);
success = [d writeToFile:@"/tmp/WriteTest.txt" options:NSDataWritingAtomic error:NULL];
(void) stat("/foo",&sb);
assert(success);
}

这两个电话只是标记;他们可以很容易地看到-writeToFile生成哪些文件系统操作:options:error:.

您可以使用以下命令查看文件系统行为:

$sudo fs_usage -f filesys -w WriteTest

其中“WriteTest”是我的测试程序的名称.

以下是生成的fs_usage输出的摘录:

14:33:10.317 stat [2] / foo
14:33:10.317 lstat64 private / tmp / WriteTest.txt
14:33:10.317打开F = 5(RWC__E)private / tmp / .dat2f56.000
14:33:10.317写F = 5 B = 0x12
14:33:10.317 fsync F = 5
14:33:10.317关闭F = 5
14:33:10.318重命名private / tmp / .dat2f56.000
14:33:10.318 chmod private / tmp / WriteTest.txt
14:33:10.318 stat [2] / foo

你可以清楚地看到围绕-writeToFile的“stat”调用:options:error:call,这意味着这些调用之间的所有东西都是由-writeToFile生成的:options:error:.

它有什么作用?嗯,它实际上非常简单:

>它创建,写入,fsyncs并关闭包含数据的临时文件.
>它将临时文件重命名为您要写入的文件.
>它重置最终文件的权限.

总而言之,这是一个非常标准的UNIX风格安全保存.但问题是,这对数据完整性有何影响?需要注意的关键是fsync不保证在返回之前将所有数据都推送到磁盘.这个问题有一个漫长而复杂的历史,但总结是fsync被称为方式太多次,对于太多性能敏感的位置,它可以做出保证.这意味着您可能会遇到所有文件损坏问题,如下所述:

o“iProcrastinate_Bad_2.ipr”和“iProcrastinate_Bad_3.ipr”只包含错误的数据.这可能发生如下:

> App创建临时文件.
> App写入临时文件.响应这个内核:

一个.在磁盘上分配一组块
湾将它们添加到文件中
C.扩展文件的长度
d.复制写入缓冲区缓存的数据

> App fsyncs并关闭文件.内核通过调度要尽快写入的数据块来响应.
> App将临时文件重命名为真实文件.
>系统内核恐慌.
>当系统重新启动时,将从日志中恢复步骤1,2a..2c,3和4中的更改,这意味着您具有包含无效数据的有效文件.

o“iProcrastinate_Bad_1.ipr”只是上述内容的略微变化.如果你用十六进制编辑器打开文件,你会发现它看起来很好,除了偏移量为0x6000..0x61ff的数据范围,它似乎包含与你的应用程序完全无关的数据.值得注意的是,这个数据的长度为0x200字节,恰好是一个磁盘块.因此,似乎内核设法将所有用户数据写入磁盘,除了这一块.

那么这会让你离开?它不太可能 – [NSData writeToFile:options:error:]将比现有的更强大;正如我之前提到的,这样的变化往往会对整体系统性能产生负面影响.这意味着您的应用必须解决此问题.

在这方面,有三种常用方法可以强化您的应用:

A. F_FULLFSYNC – 您可以通过使用F_FULLFSYNC选择器调用将文件提交到永久存储器.你可以在你的应用程序中使用这个来代替 – [NSData writeToFile:options:error:]用您自己的代码调用F_FULLFSYNC而不是fsync.

这种方法最明显的缺点是F_FULLFSYNC非常慢.

B. journalling – 采用更强大的文件格式的另一种选择,也许支持日志记录.一个很好的例子是SQLite,您可以直接使用或通过Core Data使用.

C.更安全的保存 – 最后,您可以通过备份文件实现更安全的保存机制.在调用 – [NSData writeToFile:options:error:]来编写文件之前,您可以将以前的文件重命名为其他名称,并保留该文件以防万一.如果在打开主文件时发现它已损坏,则会自动恢复为备份.

在这些方法中,我更倾向于B,特别是使用Core Data接近B,因为Core Data提供了超出数据完整性的许多好处.但是,对于快速修复选项,C可能是您最好的选择.

如果您对此事有任何疑问,请与我们联系.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我正在用TitaniumDeveloper编写一个应用程序,它允许我使用Javascript,PHP,Ruby和Python.它为API提供了一些可能需要的标准功能,但缺少的是全局事件.现在我想将全局热键分配给我的应用程序并且几乎没有任何问题.现在我只针对MAC,但无法找到任何Python或Ruby的解决方案.我找到了Coc
我的问题是当我尝试从UIWebView中调用我的AngularJS应用程序中存在的javascript函数时,该函数无法识别.当我在典型的html结构中调用该函数时,该函数被识别为预期的.示例如下:Objective-C的:-(void)viewDidLoad{[superviewDidLoad];//CODEGOESHERE_webView.d
我想获取在我的Mac上运行的所有前台应用程序的应用程序图标.我已经使用ProcessManagerAPI迭代所有应用程序.我已经确定在processMode中设置了没有modeBackgroundOnly标志的任何进程(从GetProcessInformation()中检索)是一个“前台”应用程序,并显示在任务切换器窗口中.我只需要
我是一名PHP开发人员,我使用MVC模式和面向对象的代码.我真的想为iPhone编写应用程序,但要做到这一点我需要了解Cocoa,但要做到这一点我需要了解Objective-C2.0,但要做到这一点我需要知道C,为此我需要了解编译语言(与解释相关).我应该从哪里开始?我真的需要从简单的旧“C”开始,正
OSX中的SetTimer在Windows中是否有任何等效功能?我正在使用C.所以我正在为一些软件编写一个插件,我需要定期调用一个函数.在Windows上,我只是将函数的地址传递给SetTimer(),它将以给定的间隔调用.在OSX上有一个简单的方法吗?它应该尽可能简约.我并没有在网上找到任何不花哨的东西
我不确定引擎盖下到底发生了什么,但这是我的设置,示例代码和问题:建立:>雪豹(10.6.8)>Python2.7.2(由EPD7.1-2提供)>iPython0.11(由EPD7.1-2提供)>matplotlib(由EPD7.1-2提供)示例代码:importnumpyasnpimportpylabasplx=np.random.normal(size=(1000,))pl.plot
我正在使用FoundationFramework在Objective-C(在xCode中)编写命令行工具.我必须使用Objective-C,因为我需要取消归档以前由NSKeyedArchiver归档的对象.我的问题是,我想知道我现在是否可以在我的Linux网络服务器上使用这个编译过的应用程序.我不确定是否会出现运行时问题,或者可
使用cocoapods,我们首先了解一下rvm、gem、ruby。rvm和brew一样,但是rvm是专门管理ruby的版本控制的。rvmlistknown罗列出ruby版本rvminstall版本号   可以指定更新ruby版本而gem是包管理gemsource-l查看ruby源gemsource-rhttps://xxxxxxxx移除ruby源gemsou
我有一个包含WebView的Cocoa应用程序.由于应用程序已安装客户群,我的目标是10.4SDK.(即我不能要求Leopard.)我有两个文件:index.html和data.js.在运行时,为了响应用户输入,我通常会使用应用程序中的当前数据填充data.js文件.(data.js文件由body.html上的index.html文件用于填充
如何禁用NSMenuItem?我点击后尝试禁用NSMenuItem.操作(注销)正确处理单击.我尝试通过以下两种方式将Enabled属性更改为false:partialvoidLogout(AppKit.NSMenuItemsender){sender.Enabled=false;}和partialvoidLogout(AppKit.NSMenuItemsender){LogoutI
我在想,创建一个基本上只是一个带Web视图的界面的Cocoa应用程序是否可行?做这样的事情会有一些严重的限制吗?如果它“可行”,那是否也意味着你可以为Windows应用程序做同样的事情?解决方法:当然可以创建一个只是一个Cocoa窗口的应用程序,里面有一个Web视图.这是否可以被称为“可可应
原文链接:http://www.cnblogs.com/simonshi2012/archive/2012/10/08/2715464.htmlFrom:http://www.idev101.com/code/Cocoa/Notifications.htmlNotificationsareanincrediblyusefulwaytosendmessages(anddata)betweenobjectsthatotherwi
如果不手动编写GNUmake文件,是否存在可以理解Xcode项目的任何工具,并且可以直接针对GNUstep构建它们,从而生成Linux可执行文件,从而简化(略微)保持项目在Cocoa/Mac和GNUstep/Linux下运行所需的工作?基本上,是否有适用于Linux的xcodebuild样式应用程序?几个星期前我看了pbtomake
我正在将页面加载到WebView中.该页面有这个小测试Javascript:<scripttype="text/javascript">functiontest(parametr){$('#testspan').html(parametr);}varbdu=(function(){return{secondtest:function(parametr){$('#testspan&#039
我正在尝试使用NSAppleScript从Objective-C执行一些AppleScript…但是,我正在尝试的代码是Yosemite中用于自动化的新JavaScript.它在运行时似乎没有做任何事情,但是,正常的AppleScript工作正常.[NSAppactivateIgnoringOtherApps:YES];NSAppleScript*scriptObject=[[NSApple
链接:https://pan.baidu.com/s/14_im7AmZ2Kz3qzrqIjLlAg           vjut相关文章Python与Tkinter编程ProgrammingPython(python编程)python基础教程(第二版)深入浅出PythonPython源码剖析Python核心编程(第3版)图书信息作者:Kochan,StephenG.出
我正在实现SWTJava应用程序的OSX版本的视图,并希望在我的SWT树中使用NSOutlineView提供的“源列表”选项.我通过将此代码添加到#createHandle()方法来破解我自己的Tree.class版本来实现这一点:longNSTableViewSelectionHighlightStyleSourceList=1;longhi=OS.sel_regist
我的Cocoa应用程序需要使用easy_install在用户系统上安装Python命令行工具.理想情况下,我想将一个bash文件与我的应用程序捆绑在一起然后运行.但据我所知这是不可能的,因为软件包安装在Python的“site-packages”目录中.有没有办法创建这些文件的“包”?如果没有,我应该如何运行ea
摘要: 文章工具 收藏 投票评分 发表评论 复制链接 Swing 是设计桌面应用程序的一个功能非常强大工具包,但Swing因为曾经的不足常常遭到后人的诟病.常常听到旁人议论纷纷,”Swing 运行太慢了!”,”Swing 界面太丑嘞”,甚至就是说”Swing 简直食之无味”. 从Swing被提出到现在,已是十年光景,Swing早已不是昔日一无是处的Swing了. Chris Adamson 和我写
苹果的开发:   我对于Linux/Unix的开发也是一窍不通,只知道可以用Java.不过接触了苹果过后,确实发现,世界上确实还有那么一帮人,只用苹果,不用PC的.对于苹果的开发,我也一点都不清楚,以下是师兄们整理出来的网站. http://www.chezmark.com/osx/    共享软件精选 http://www.macosxapps.com/    分类明了,更新及时的一个重要Mac