I´m trying to store some data in a file. I open the file the first iteration, and add the info. But, when the algorithm end, file size is 5kbs, it must be like 2,5 Mbs.
if (!isopen)
{
NSArray *paths;
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// Check DD
if ([paths count] > 0)
{
NSLog(#"Found a path");
fichero2 = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"out2.raw"];
NSLog(#"path %#",fichero2);
} else {
//d'oh, something went really wrong
NSLog(#"ERROR: could not open %s\n", "out.raw");
return -1;
}
isopen = 1;
}
else
{
// Write file
NSMutableData *data = [NSMutableData dataWithLength:1152*2];
[data appendBytes:((SInt16 *)[audioProcessor audioBuffer].mData) length:1152*2];
[data writeToFile:fichero2 atomically:YES];
}
Is really need to close the file? It auto close itself? So, why data is not stored?
I think you are creating a new NSData each loop,
Should be outside the dope of the iteration, no?
NSMutableData *data = [NSMutableData dataWithLength:1152*2];
then for
[data appendBytes:((SInt16 *)[audioProcessor audioBuffer].mData) length:1152*2];
[data writeToFile:fichero2 atomically:YES];
Related
I have an iOS app that at times needs to store UIImage objects locally.
I am using [UIImagePNGRepresentation(image) writeToFile:full_path options:NSAtomicWrite error:nil]; to save the image and [file_manager removeItemAtPath:full_path error:NULL]; to delete the file.
This all works great, however, whenever I delete a file, should I decide to save a new file (which just so happens to have the same name as the old file), the save code doesn't work and returns the following error:
: ImageIO: CGImageReadCreateDataWithMappedFile 'open' failed
error = 2 (No such file or directory)
: ImageIO: CGImageReadCreateDataWithMappedFile 'open' failed
error = 2 (No such file or directory)
: ImageIO: PNG zlib error
So heres what I don't get, why can't I save a file with the same name as the old file, after I have deleted the old file?
The reason I ask this, is that, my app will save certain image files and then when they are no longer needed, my app will delete them. However, there are times when my app needs the image files again (could be a few hours after deletion or a few weeks). When this happens, my app will load the appropriate image data and then try to save it. And thats when the error occurs.
Whats going wrong here?
Thanks for your time, Dan.
UPDATE - Here are the methods I have setup to save/access and delete my image files
-(void)save_local_image:(UIImage *)image :(NSString *)file_name {
// Get the app documents directory link.
NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// Add the new file name to the link.
NSString *database_link = [[NSString alloc] initWithString:[documents stringByAppendingPathComponent:file_name]];
// Save the image data locally.
[UIImagePNGRepresentation(image) writeToFile:database_link options:NSAtomicWrite error:nil];
}
-(UIImage *)get_local_image:(NSString *)file_name {
// Create the return data.
UIImage *image_data = nil;
// Get the app documents directory.
NSArray *directory = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] error:NULL];
// Only check for data if at least
// one file has been saved locally.
if ([directory count] > 0) {
// Loop through the different local files.
for (NSString *path in directory) {
// Get the full local file URL.
NSString *full_path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:path];
// Get the range of the file name.
NSRange range = [full_path rangeOfString:file_name];
// Get the image data if it exists.
if ((range.location != NSNotFound) || (range.length == [file_name length])) {
// Load the image file in.
image_data = [UIImage imageWithContentsOfFile:full_path];
break;
}
}
}
return image_data;
}
-(void)delete_local_image:(NSString *)file_name {
// Get the app documents directory.
NSArray *directory = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] error:NULL];
// Only check for data if at least
// one file has been saved locally.
if ([directory count] > 0) {
// Loop through the different local files.
for (NSString *path in directory) {
// Get the full local file URL.
NSString *full_path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:path];
// Get the range of the file name.
NSRange range = [full_path rangeOfString:file_name];
// Delete the local image data if it exists.
if ((range.location != NSNotFound) || (range.length == [file_name length])) {
NSError *testError = nil;
// Delete the image file.
NSFileManager *file_manager = [[NSFileManager alloc] init];
BOOL success = [file_manager removeItemAtPath:full_path error:&testError];
NSLog(#"%d", success);
if (testError != nil) {
NSLog(#"%#", testError.localizedDescription);
}
break;
}
}
}
}
I am using this to save and read:
- (void) saveImageToFile:(NSString *) urlImg withNameNumber:(int)numberName andQuestionId:(int) questionID
{
NSString* documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString* foofile = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"gallery%d%d.jpg",numberName,questionID]];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
if (!fileExists) {
NSData *tempImgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#",#"https://testurl/",urlImg]]];
NSString *filename = [NSString stringWithFormat:#"gallery%d%d.jpg",numberName,questionID];
NSString *imagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:filename];
[tempImgData writeToFile:imagePath atomically:YES];
}
}
-(UIImage*) readImageFromFile:(int)numberName andQuestionId:(int) questionID
{
NSString * documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/gallery%d%d.jpg",documentsDirectoryPath,numberName,questionID]];
}
At now I save file by recording it from AVAudioUnitEQ.
[mainEQ installTapOnBus:0 bufferSize:0 format:[mainEQ outputFormatForBus:0] block:^(AVAudioPCMBuffer *buf, AVAudioTime *when){
if(!recordIsGoing){
[mainEQ removeTapOnBus:0];
}
else{
[writeAudioFile writeFromBuffer:buf error:nil];
// NSLog(#"%lld", writeAudioFile.length);
}
}];
But this method requires a prior file playback . Is there a way to save the mixed file without playing ?
UPD: I can get AUAudioUnit.outputBusses[0] to mainEQ.
The challenge now is to take out the data and hope that they will be such what I need.
RESOLVED: Issue been resolved by this answer Can I use AVAudioEngine to read from a file, process with an audio unit and write to a file, faster than real-time?
I think you can do this by first converting your data into NSData and storing it. When you retrieve it back, you can convert it back.
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:buf];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"yourfilename.dat"];
// Save it into file system
[data writeToFile:dataPath atomically:YES];
I test to see if a directory is saving and it doesn't seem that it is.
Here is what I have, it's essentially creating a list of which files have been uploaded to Dropbox. DropboxList is declared in the header file and then synchronized.
int i = 0;
DropboxList = [[NSMutableDictionary alloc]init];
do {
[DropboxList setObject:#"NO" forKey:[NSNumber numberWithInt:i]];
i++;
} while (i < sortedFiles.count);
NSLog(#"dropbox list is %#", DropboxList);
NSArray *dropBoxPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dropBoxDocumentsDirectory = [dropBoxPaths objectAtIndex:0];
NSString *dropBoxDataPath = [dropBoxDocumentsDirectory stringByAppendingPathComponent:#"/DropboxUploads"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dropBoxDataPath]) {
[[NSFileManager defaultManager] createDirectoryAtPath:dropBoxDataPath withIntermediateDirectories:NO attributes:nil error:nil];
}
NSString *filePath = [dropBoxDataPath stringByAppendingPathComponent:#"dropboxList.out"];
[DropboxList writeToFile:filePath atomically:YES];
NSMutableDictionary *newDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
NSLog(#"newDictionary list is %#", newDictionary);
Here is my console:
dropbox list is {
0 = NO;
3 = NO;
2 = NO;
1 = NO;
4 = NO;
}
newDictionary list is (null)
I've tried alloc init for the newDictionary before writing and I get the same result. Any ideas?
The problem is with the following line
[DropboxList setObject:#"NO" forKey:[NSNumber numberWithInt:i]];
DropboxList writeToFile only works with the valid property list. For a NSMutableDictionary to be a valid property list object, its keys should be string type instead of NSNumber.
Solution
[DropboxList setObject:#"NO" forKey:[NSString stringWithFormat:#"%d",i]]];
Also, make use of the writeToFile return parameter to validate.
BOOL isWritten = [DropboxList writeToFile:filePath atomically:YES];
if (isWritten)
{
NSMutableDictionary *newDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
NSLog(#"newDictionary list is %#", newDictionary);
{
else
{
NSLog(#"Something went wrong");
}
Okay, so my problem was that I had NSNumbers as the keys, which doesn't work. I made the keys strings, and we're golden.
I want to call images from different folder, would you please help me to implement this;
I have this structure for my folders :
Folder1
file1
image1.jpg
file2
image2.jpg
file3
image3.jpg
Folder2 ....
inside of each file%d I have one image%.jpg
I want to call my images in loop,
for (i = 1; i > image; i++)
{
NSString *image = [NSString stringWithFormat:#"image%d.jpg", i];
But my question is how to enter to the folders and get images
can I have something like this :
stringWithFormat:#"Folder%d/File%d/image%d" ofType:#"jpg"
what is the best way?
Thanks in advance!
Here are a few useful code snippets that work for me.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *mapDirPath = [documentsDirectory stringByAppendingPathComponent:#"/MapCache"];
// Creating a directory in the documents directory
NSError* error;
if (![[NSFileManager defaultManager] fileExistsAtPath:mapDirPath])
[[NSFileManager defaultManager] createDirectoryAtPath:mapDirPath withIntermediateDirectories:NO attributes:nil error:&error];
// loading an image
NSString *filePath = [self.localImagePath stringByAppendingPathComponent: key];
if ( [[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
UIImage* image = [UIImage imageWithContentsOfFile:filePath];
return image;
}
// Writing an image
[[NSFileManager defaultManager] createFileAtPath:filePath contents:remoteData attributes:nil];
Hope that helps
Of course, if you're reading images from your bundle, you want this instead
[[NSBundle mainBundle] pathForResource: #"filename" ofType:#"png" directory: #"directory1"]
Right, this is how I would do it.
for (f = 1; f <= numberOfFolders; i++) {
for (i = 1; i <= numberOfImages; i++) {
NSString* file = [NSString stringWithFormat: #".../Folder%d/File%d/image%d.jpg", f, i, i];
NSImage* image = [NSImage imageNamed: file];
// Do something with the image
}
}
A note: I don't know where Folder1/Folder2... etc are, so I used '.../' on the code. Be sure to fill that part appropriately.
Iterate folders and images appending the image path to the library path:
NSString * libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
for (NSUInteger f = 1; f <= numFolders; i++) {
for (NSUInteger i = 1; i <= numImages; i++) {
// Create the image path
NSString * imagePath = [NSString stringWithFormat:#"%#/Folder%d/File%d/image%d.jpg", libraryPath, f, i, i];
// Check if file exists
if ( [[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
UIImage * image = [UIImage imageWithContentsOfFile:imagePath];
// Use image...
}
else {
NSLog(#"Image not found.");
}
}
}
I am new to IOS programming. I want to write some data into file. I have opened successfully the file in Document path. But fwrite its not working as expected. If I open the file its empty. Its my code I'm using. What I'm doing wrong.
typedef struct test {
int a;
} TEST_OBJ;
TEST_OBJ test_obj1;
test_obj1.a = 5;
TEST_OBJ *data_ptr = &test_obj1;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:#"MyFile1.txt"];
//This is working fine.
// [data writeToFile:appFile atomically:YES];
NSFileManager *fileManager = [[NSFileManager alloc]init];
char const *path = [fileManager fileSystemRepresentationWithPath:appFile];
FILE *fp = fopen(path, "w+b");
// This write is not working. File is empty.
int cnt = fwrite (data_ptr , 1 , sizeof(test_obj1) , fp );
fclose(fp);
fp = NULL;
Anyone pls tell me what I'm doing wrong?
I recommend you use NSData instead of C functions.
NSData *myData = [[NSData alloc] initWithBytes:bytes length:length];
[myData writeToFile:path atomically:YES];
you can use NSData,NSArray,NSDictionary,they have [writeToFile: atomically:] method ,it can write the data into the file.
if you must C to read and write filestream,you can use my method below , it can add arrayString to the file .
- (void)putArrayString:(NSString *)arrayString toFilePath:(NSString *)filePath
{
FILE *fileStream = fopen([filePath UTF8String], "a+");
if(fileStream == NULL)
{
fclose(fileStream);
fileStream = fopen([filePath UTF8String], "w+");
fputs([arrayString UTF8String], fileStream);
}
else
{
fputs([arrayString UTF8String], fileStream);
}
fclose(fileStream);
}
I have changed the mode of opening a+ its writing and reading properly now. Thanks all for your help.
See if you can use this code:
https://github.com/RIKSOF/three20/blob/master/src/extThree20RemoteObject/Source/TTObjectModel.m
Start reading from the encodeToDocument method. It writes all properties of an object in to a JSON or XML file.
Any subclass of this class having any property is properly written back.