Reputation: 20237
I need to be able to create a large "dummy" file (around 1 GB) quickly. I am currently looping over a byte array and appending it to the file, but this results in may separate disk hits:
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:self.path];
[handle seekToEndOfFile];
while (shouldContinue)
{
NSData *dummyData = [self buildDummyData];
[handle writeData:dummyData];
}
But this takes around 7 seconds to complete. I would like it to complete in less than 1 second. Is there a way to create a file and allocate its size without needing to append bytes to it?
Upvotes: 2
Views: 2631
Reputation: 12819
If you want to stay in Objective-C, use NSFileHandle
like you do in your example:
NSFileHandle *file = [NSFileHandle fileHandleForWritingAtPath:dummyFilePath];
if (file == nil) {
[[NSFileManager defaultManager] createFileAtPath:dummyFilePath contents:nil attributes:nil];
file = [NSFileHandle fileHandleForWritingAtPath:dummyFilePath];
}
[file truncateFileAtOffset:sizeInMB * 1024 * 1024];
[file closeFile];
Note that this is sloooow. Writing a 1GB file takes over 30 seconds for me.
Another way to do it would be to do a write:
[file seekToFileOffset:sizeInMB * 1024 * 1024];
const unsigned char bytes[] = {1};
[file writeData:[NSData dataWithBytes:bytes length:sizeof(bytes)]];
This was even slower for me, taking 55 seconds for the 1GB.
Upvotes: 1
Reputation: 6211
You can check this answer. It says that you can lseek() past the end of file (EOF) then write something. The gap between the initial end of file and the bytes you wrote will return 0's if queried.
Upvotes: 2
Reputation: 41801
You can use truncate
to set the length of a file directly:
int success = truncate("/path/to/file", 1024 * 1024 * 1024);
if (success != 0) {
int error = errno;
/* handle errors here. See 'man truncate' */
}
Upvotes: 7