views:

96

answers:

2

Short version: I think I'm asking for a file too soon, but it's pretending like it's ready. Am I missing something?

Slightly longer version: I am writing files to disk. Before I do so, I have the user add some meta data, including the new file name. Once the user is done, the screen goes away and the program writes the file to disk. The user can then look at a list of files. That list is generated by reading the contents of a folder. The new file is in the list of files, but when I try to extract info from the file to display (e.g. file size) the program crashes. As best as I can tell, the crash occurs because, while the file is there in name, it's not available to be read. (By the way, these are small files - a few hundred k.)

First, is it possible that a file shows up in the directory but isn't all there yet? a And second, if so, how do I check to see if the file is ready to be read?

Thanks much.

UPDATE:

Thanks. I'll try to add more info. I'm recording an audio file with AVAudioRecorder. The init line is:

soundrecording = [[AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:&error];

The program goes through it's UI updates and metering and all that. When the audio is stopped, I call:

[soundrecording stop];

and when everything else is updated and ready to move on, I call:

[soundrecording release];
soundrecording=NULL;

As far as I understand, this should take care of releasing the file, yes?

Thanks again.

+1  A: 

The first thing I would do is confirm that you're right about the file not being ready yet. To do that, sleep your program for a second or two after writing and before reading. A few hundred KB should not take longer than that to be ready.

If it still fails, my guess is that you haven't closed the file handle that you used to write it. It may be unready for reading because the file system thinks you might keep writing.

Usually, the way to check to see if a file is ready is to attempt to open it. If that succeeds, you can read it. Or if it fails with an error, you can handle the error gracefully:

  • In a command-line utility, you might print the error and quit, and the user could try again.
  • If it's a background program that should not quit, like a server, you could log the error. You might also try again automatically after a delay. If it's a big deal kind of error, you might want to have the program email you about it.
  • In an GUI window app, you probably want to show an error dialog or panel, and then give the user an opportunity to retry.
Kevin Conner
That would be my guess. Read access denied because it's still open for writing.
Anon.
I've added more specific info above.
Eric Christensen
A: 

Now that you have added sample code, I can say some more.

First, the class reference seems to say that the stop method will close the file. However it also seems to suggest that there is an underlying audio session going on, and possibly some conversion. I think I recall that the iPhone's Voice Notes app, which probably uses this API, has to do some work to compress a long recording after it's completed.

So I support your hunch. I think that your file may not be closed yet, but on another thread that is processing the recorded data into a proper format to save.

You probably want to set a NSTimer to attempt to open the file every second or so, so that your user interface can perk up when it's done. You probably want to show a "Please wait" sort of message in the meantime, or otherwise let the user know it's working.

Kevin Conner
Thanks. It looks like the file isn't being released. After the the AVAudioRecorder is stopped and released and the user calls up the menu, I have: NSString* filePath=[[NSBundle mainBundle] pathForResource:fileName ofType:@"wav" inDirectory:@"../Documents"]; while([[NSFileManager defaultManager] isReadableFileAtPath:filePath]==NO){ NSLog(@"ready?"); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; }And it's just sitting there printing out "ready?" forever. Any idea how I can track down what's holding on to the audio file?Thanks again.
Eric Christensen
Perhaps it is never being written because you're accidentally outside the sandbox. Try getting the Documents folder in the canonical way:NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0];
Kevin Conner
Thanks. I know the files are being written because after the crash, I reopen the app and the files are there. In the mean time, I've noticed the new file causes the hang only if I open the list before I record a file. (i.e. open the list view (usually to delete the previous file), close the list view, open the record view, record a file, close the record view, and open the list view again, at which point it hangs.) I guess that means the problem is how I'm reusing the list view. I'm releasing the list each close and recreating each open, so I'm not sure what's carrying over. Anyway, Thanks.
Eric Christensen
I'd suggest you put a breakpoint in the `dealloc` of your list view controller. If it's getting released completely, that's one way to tell. You might also try looking for leaks with Instruments.
Kevin Conner