Re: NSDocument save incremental file package in-place
Re: NSDocument save incremental file package in-place
- Subject: Re: NSDocument save incremental file package in-place
- From: Trygve Inda <email@hidden>
- Date: Sat, 01 Mar 2014 15:26:23 -0800
- Thread-topic: NSDocument save incremental file package in-place
>
> On 1 Mar 2014, at 19:11, Trygve Inda <email@hidden> wrote:
>
>>> On Mar 1, 2014, at 07:23 , Trygve Inda <email@hidden> wrote:
>>>
>>>> The problem is that when there is a very small change (just adding or
>>>> removing one of the files in the package), the system does not save in
>>>> place.
>>>>
>>>> Rather it reads the previous package file completely, writes out a copy of
>>>> the package (400 MB) and then renames it.
>>>>
>>>> How can I get it to save in place?
>>>
>>> AFAIK, NSDocument never saves in place, and isn’t intended to (for safety
>>> reasons — what happens if your app crashes after some of the files have been
>>> updated but not others?).
>>>
>>> Instead, it achieves its package performance optimization by hard-linking
>>> unchanged files in the new (saved) package to files in the old (original)
>>> package. If your save is taking 40 seconds, that could mean:
>>>
>>> — The document is on a file system that doesn’t support hard linking.
>>>
>>> — The document is on a file system where hard linking 7500 files takes 40
>>> seconds.
>>>
>>> — You didn’t preserve the original file sub-wrappers from the directory
>>> wrapper created when the document was opened, so NSDocument thinks all the
>>> files have changed. Note that it’s undocumented (again, AFAIK) what criteria
>>> NSDocument uses** to decide when a particular file wrapper represents “no
>>> change”, so it’s safest to keep the original NSFileWrapper objects from open
>>> time until save time.
>>>
>>>
>>>
>>> ** The most likely possibilities are ‘==’ on file wrappers, ‘isEqual:’ on
>>> file
>>> wrappers, or comparison of mod date and/or size of the actual files, but it
>>> could be something more obscure.
>>>
>>
>>
>> When a file is opened, my NSDocument subclass uses
>>
>> -(BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString
>> *)typeName error:(NSError **)outError
>>
>> After loading it, I call
>>
>> [self setDocumentFileWrapper:fileWrapper];
>>
>> Which stores the fileWrapper in my Document object for later use.
>>
>>
>> Later, when saving I use
>>
>> -(NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError
>> **)outError
>>
>> Even if I only call
>>
>> return documentFileWrapper;
>>
>> So the document is saved with zero changes, it takes 40 seconds on my
>> package with 7500 sub-items. It should happen almost instantly, but it
>> doesn't.
>>
>> I am using a normal Mac HFS system.
>>
>> I really need this to be faster.
>
> It is -[NSFileWrapper writeToURL:options:originalContentsURL:error:] which has
> the feature of writing out hard links for efficiency. But it only does it if
> requested, by passing a suitable URL as the original contents URL. It is my
> suspicion that NSDocument does not do this for you. You could set a breakpoint
> to test this.
>
> If so, it becomes your responsibility to override -writeToURL:… in your
> document subclass and write the file wrapper yourself.
I have a top level FileWrapper which contains the wrappers for all my files.
Is there any sample code that would help me figure out the right way to do
this?
[NSFileWrapper writeToURL:options:originalContentsURL:error:]
Seems to call my method to get the top level fileWrapper.
When I set a breakpoint, I see the writeToURL is a temp folder and the
originalContentsURL is indeed the file package on disk.
So why isn't it hard linking?
Or is hard linking just really that slow?
Trygve
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden