Write to file without overwriting ObjC - iphone

I would like to write text to a file, but when searching for solution, I find "read-append-write" everywhere, but the file is too large for the memory of an iOS device, and it freezes, and resprings.
Is there any other solution to do it?

You can use the NSFileHandle class in order not to have to read the whole file into memory (which is, by the way, bad practice for any file!):
NSFileHandle *fh = [NSFileHandle fileHandleForWritingAtPath:#"/path/to/file.ext"];
[fh seekToEndOfFile];
NSData *data = // obtain an NSData somehow
[fh writeData:data];
[fh closeFile];

Related

dataWithContentsOfFile:filepath of NSData sometimes works, sometimes has no function

I used the codes below to load image file in app bundle.
The codes work! imageData does NOT return 0x0
NSMutableString *sss;
sss=[[NSMutableString alloc] initWithString: [[NSBundle mainBundle] resourcePath]];
[sss appendString:#"/"] ;
[sss appendString:#"thumbnail.png"];
NSData *imageData = [NSData dataWithContentsOfFile:sss];
but the codes below in which almost everything is same have no function, imageData always DOES return 0x0, it looks like [NSData dataWithContentsOfFile:filepath ] does not work for large size image file
NSMutableString *sss;
sss=[[NSMutableString alloc] initWithString: [[NSBundle mainBundle] resourcePath]];
[sss appendString:#"/"] ;
[sss appendString:#"original.png"];
NSData *imageData = [NSData dataWithContentsOfFile:sss];
Both of thumbnail.png and original.png are in the same directory of main bundle.
thumbnail.png
original.png
Welcome any comment
Thanks
Marc
It won't have anything to do with the size of the file. Check and see if you've spelled the file name correctly in your code. The file names are case-sensitive, so if the file is named original.PNG, then you'll need to make sure it is written that way in code as well.
Make sure that the original.png file has been added to your project, and if so, try removing it from your project and re-adding it. When you drag the file into your project, make sure the option "copy files..." is checked.
check out if it really contains on resource .
check that file is in:
Targets/ProductName/Copy Bundle Resources
I also think that the file has not been added to resources. Check the 'Resources' folder in your xcode project, and if it isnt there, put it in there. Either by dragging it in there, or by rightclicking -> new file.

ZipArchive memory problems on iPhone for large archive

I am trying to compress multiple files into a single zip archive and I am running into low memory warning. Since the complete zip file is loaded into the memory I guess that's the problem. Is there a way by which I can manage the compression/decompression better using ZipArchive so that not all the data is in the memory at once?
Thanks!
After doing some investigation on alternatives to ZipArchive I found another project called Objective-zip that seems to be a little better than ZipArchive. Here is the link:
http://code.google.com/p/objective-zip/
The API is quite simple. One thing I ran into was that in the begging I was reading data and never releasing it so if you are adding a bunch of large files to the zip file remember to release the data. Here is a little code I used:
ZipFile *zipFile = [[ZipFile alloc] initWithFileName:archivePath mode:ZipFileModeCreate];
for(NSString *path in subpaths){
NSData *data= [[NSData alloc] initWithContentsOfFile:longPath];
ZipWriteStream *stream = [zipFile writeFileInZipWithName:path compressionLevel:ZipCompressionLevelNone];
[stream writeData:data];
[stream finishedWriting];
[data release];
}
[zipFile close];
[zipFile release];
I hope this is helpful for anyone who runs into the same issue.
An easier way to deal with this is to simply change ZipArchive's method of reading the file into the NSData. Just change the following code
data = [ NSData dataWithContentsOfFile:file ];
to
data = [ NSData dataWithContentsOfMappedFile:file ];
That will cause the OS to read the file in a memory mapped way. Basically it just uses way less memory as it reads from the file as it needs to rather than loading it all into memory at once.

How can I locally save an XML file on an iPhone for when the device is offline?

My app is accessing data from a remote XML file. I have no issues receiving and parsing the data. However, I'd like to take the most current XML data and store it locally so - in the event that the user's internet service isn't available - the local data from the previous load is used.
Is there a simple way to do this? Or am I going to have to create an algorithm that will create a plist as the xml data is parsed? That seems rather tedious... I was wondering if there was an easier way to save the data as a whole.
Thanks in advance!
I don't know what format your XML data is in as you receive it, but using NSData might be helpful here, because it has very easy-to-use methods for reading/writing data from either a URL or a pathname.
For example:
NSURL *url = [NSURL URLWithString:#"http://www.fubar.com/sample.xml"];
NSData *data = [NSData dataWithContentsOfURL:url]; // Load XML data from web
// construct path within our documents directory
NSString *applicationDocumentsDir =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *storePath = [applicationDocumentsDir stringByAppendingPathComponent:#"sample.xml"];
// write to file atomically (using temp file)
[data writeToFile:storePath atomically:TRUE];
You can also easily convert an NSData object to/from a raw buffer (pointer/length) in memory, so if your data is already downloaded you might do:
NSData *data = [NSData dataWithBytes:ptr length:len]; // Load XML data from memory
// ... continue as above, to write the NSData object to file in Documents dir

read single line from text file in objective-C

i'm new to iPhone programming and coding in XCode SDK.I want to access and read the configuration file which i have placed in Resource folder in XCode,my configuration file looks like this
#key=value$
#vinu=flower$
#cathy=fruit$
I want to compare the key and access the value from configuration file.
Since i'm working with iPhone OS, i cant use NSWorkspace.Hence i'm using NSFileHandle.
This is how my code looks like,
NSString *path = [[NSBundle mainBundle] pathForResource:#"configuration" ofType:#"txt"];
NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:path];
NSString *txtString = [[NSString alloc] initWithData:
[readHandle readDataToEndOfFile] encoding:NSUTF8StringEncoding];
please let me know is the procedure correct, and how to proceed. ??
Thank You.
Do yourself a favor and save it as a plist, and not a straight text file.
However, if you need to read it in like that, the simplest way is to read it into a string and then go from there, ie:
NSString * fileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
If the file is super large and the only reasonable way to read it is line-by-line, then you can quickly see that this is something that has come up before (Particularly: Objective-C: Reading a file line by line).

Loading data files in iPhone project

How does one read a data file in an iPhone project? For example, lets say I have a static file called "level.dat" that is structured as follows:
obstacles: 10
time: 100
obstacle1: 10,20
...
I would like to read the contents of the file into a NSString then do the parsing. How do I read the contents of a file into a string? Also, where in the project should the "level.dat" file reside? Should it be under "Resources" or just in the main directory?
Thanks in advance!
See this answer: How to fopen() on the iPhone? which shows how to get access to resources in your bundle. Once you have the path, just use [NSString stringWithContentsOfFile:encoding:error:].
NSString *path = [[NSBundle mainBundle] pathForResource: #"level" ofType: #"dat"]
NSError *error = nil;
NSString *data = [NSString stringWithContentsOfFile: path
encoding: NSUTF8StringEncoding
error: &error];
While this isn't what you asked for, consider turning your files into plists. You will have to reformat them into XML, but then you can load them straight into a NSDictionary with:
dict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"levels" ofType:#"plist"]];
Have you considered putting the data in an SQLite database instead of a flat file? I find that the API is very easy to use on the iPhone.
It is how I do all of my data storage on the phone now.
If you need help parsing the data string, there's a helpful article on Cocoa For Scientist