Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Accessing a file with a changing name?

Accessing a file with a changing name?
Thread Tools
Professional Poster
Join Date: Sep 2000
Location: San Francisco
Status: Offline
Reply With Quote
Apr 5, 2003, 10:32 AM
 
I have a log file that I want to access. The problem is that the name changes every so often. The root of the name is always the same and it is always in the same directory. What's the best way to deal with this?

For instance, the file might be
~/Library/myApp/log01.txt

Or
~/Library/myApp/log02.txt

Basically, the log file gets replaced periodically with the next increment. There is never more than one log file.

I want to get the contents of the file using a URL, like this:
Code:
NSString *logContents=[NSString stringWithContentsOfURL:logURL];
My problem is that I don't know how to generate the logURL with a constantly changing file name.

thanks,
kman
     
Mac Elite
Join Date: Feb 2001
Location: Vancouver, WA
Status: Offline
Reply With Quote
Apr 5, 2003, 03:25 PM
 
Use -[NSFileManager directoryContentsAtPath:] to list all files in the directory containing your log file, look for names that match the LogXX.txt pattern, and take the one with the highest number.

You could also use -[NSFileManager fileExistsAtPath:] in a loop, starting with either Log01 or the highest-numbered file you find last time, and incrementing the number until you find the current log. But that has a good chance of taking forever to find what you're after.
Rick Roe
icons.cx | weblog
     
kman42  (op)
Professional Poster
Join Date: Sep 2000
Location: San Francisco
Status: Offline
Reply With Quote
Apr 5, 2003, 06:14 PM
 
Here's what I've tried so far:

Code:
-(IBAction)openLogFile:(id)sender { NSOpenPanel *oPanel = [NSOpenPanel openPanel]; NSString *result; [oPanel setAllowsMultipleSelection:NO]; result = [oPanel runModalForDirectory:NSHomeDirectory() file:nil types:nil]; logFile = [[oPanel filenames] objectAtIndex:0]; NSScanner *pathScanner = [NSScanner scannerWithString:logFile]; [pathScanner scanUpToString:@"/log" intoString:&logFileDirectory]; NSLog(@"logFileDirectory=%@",logFileDirectory); } -(void)getInfoFromLog { NSAutoreleasePool *logpool = [[NSAutoreleasePool alloc] init]; NSArray *directoryContents=[NSFileManager directoryContentsAtPath:logFileDirectory]; NSString *currentLogFile; NSEnumerator *enumerator = [directoryContents objectEnumerator]; id file; while (file = [enumerator nextObject]) { NSScanner *fileNameScanner = [NSScanner scannerWithString:file]; if ([fileNameScanner scanUpToString:@"log" intoString:NULL]) { currentLogFile=file; } } ...
I get a selector unknown error in [NSFileManager directoryContentsAtPath:logFileDirectory]

Any help would be great! And if you participate in Folding@Home, you can download this little helper app here . Aside from this issue, it works pretty well. You are welcome to modify the app in any way you see fit.

kman
     
Mac Elite
Join Date: Feb 2001
Location: Vancouver, WA
Status: Offline
Reply With Quote
Apr 6, 2003, 12:17 AM
 
It's probably better to use NSString's path utilities to get the parent directory of the chosen file. Replace the last three lines of -openLogFile: with:
Code:
logFileDirectory = [logFile stringByDeletingLastPathComponent];
The error you're getting is because -directoryContentsAtPath: is an instance method on NSFileManager, not a class method. You'll want to use the class method +defaultManager to get an instance you can manipulate. With that change, and eliminating further unnecessary use of NSScanner:
Code:
-(void)getInfoFromLog { NSAutoreleasePool *logpool = [[NSAutoreleasePool alloc] init]; NSArray *directoryContents = [[NSFileManager defaultManager] directoryContentsAtPath:logFileDirectory]; NSString *currentLogFile; NSEnumerator *enumerator = [directoryContents objectEnumerator]; id file; while ((file = [enumerator nextObject])) { if ([file rangeOfString:@"log" options:NSCaseInsensitiveSearch].location != NSNotFound) currentLogFile = file; } ...
BTW, unless your log-processing code involves the creation of a whole lot of autoreleased objects, you don't really need the local autorelease pool. You might want to test performance with and without -- it's said that premature optimization is the root of all evil.
Rick Roe
icons.cx | weblog
     
kman42  (op)
Professional Poster
Join Date: Sep 2000
Location: San Francisco
Status: Offline
Reply With Quote
Apr 6, 2003, 10:30 AM
 
Originally posted by Rickster:
It's probably better to use NSString's path utilities to get the parent directory of the chosen file. Replace the last three lines of -openLogFile: with:
Code:
logFileDirectory = [logFile stringByDeletingLastPathComponent];
The error you're getting is because -directoryContentsAtPath: is an instance method on NSFileManager, not a class method. You'll want to use the class method +defaultManager to get an instance you can manipulate. With that change, and eliminating further unnecessary use of NSScanner:
Code:
-(void)getInfoFromLog { NSAutoreleasePool *logpool = [[NSAutoreleasePool alloc] init]; NSArray *directoryContents = [[NSFileManager defaultManager] directoryContentsAtPath:logFileDirectory]; NSString *currentLogFile; NSEnumerator *enumerator = [directoryContents objectEnumerator]; id file; while ((file = [enumerator nextObject])) { if ([file rangeOfString:@"log" options:NSCaseInsensitiveSearch].location != NSNotFound) currentLogFile = file; } ...
BTW, unless your log-processing code involves the creation of a whole lot of autoreleased objects, you don't really need the local autorelease pool. You might want to test performance with and without -- it's said that premature optimization is the root of all evil.
Thanks! That helps tremendously. I had no idea there was an NSString method for deleting the last path component. That has been the bane of learning Cocoa. There are all of these great classes and methods that one may never know about. I never would have thought to look in NSString for a method to deleted a portion of a path!

Also, the autorelease pool is there because that same method actually goes on to retrieve the info off of the web.

kman
     
kman42  (op)
Professional Poster
Join Date: Sep 2000
Location: San Francisco
Status: Offline
Reply With Quote
Apr 6, 2003, 11:38 AM
 
One last question. What's the '.location' in the rangeOfString line?

thanks,
kman
     
Mac Elite
Join Date: Feb 2001
Location: Vancouver, WA
Status: Offline
Reply With Quote
Apr 6, 2003, 03:19 PM
 
-rangeOfString: returns an NSRange, which is a struct. ".location" gets an element of that struct.

Yeah, there are many things in Cocoa -- especially in Foundation -- that aren't in places you'd first think to look for them. (It all makes sense eventually though.) The best way to learn is just to explore, I think.
Rick Roe
icons.cx | weblog
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 03:21 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2