I have gotten this code from somewhere else with a little editing which allows to go through all the directories with the starting path specified using enumeratorAtPath. With this code i am able to retrieve files with a certain extension which has read attribute using isReadableFileAtPath. What i would like is to retrieve all files with any extension which has read attribute and classify them into different categories based on their last folder name.
Example if i have a path /a/b/c/example.plist, /a/b/c/example.plist would be classified under c.
- (NSString *) retrievePaths
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableString *filePaths = [[NSMutableString alloc] init];
NSDirectoryEnumerator *dirnum = [[NSFileManager defaultManager] enumeratorAtPath:#"/"];
NSString *nextItem = [NSString string];
int i = 0;
while( (nextItem = [dirnum nextObject]))
{
if([[nextItem pathExtension] isEqualToString:#"db"] || [[nextItem pathExtension] isEqualToString:#"sqlitedb"] || [[nextItem pathExtension] isEqualToString:#"sqlite"]) {
if([fileManager isReadableFileAtPath:nextItem])
{
i++;
[filePaths appendFormat:#"%d)",i];
[filePaths appendString:nextItem];
[filePaths appendString:#"\n"];
}
}
}
NSString *format = [NSString stringWithFormat:#"Paths : %#", filePaths];
return format;
}
Remove below if condition from your code and you will be able to get all files with readable access permission
if([[nextItem pathExtension] isEqualToString:#"db"] || [[nextItem pathExtension] isEqualToString:#"sqlitedb"] || [[nextItem pathExtension] isEqualToString:#"sqlite"])
EDIT
Updated function try this, will work for you..
- (NSString *) retrievePaths
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableString *filePaths = [[NSMutableString alloc] init];
NSString *path = #"/Assign/your/path/"; // assign your path
NSDirectoryEnumerator *dirnum = [[NSFileManager defaultManager] enumeratorAtPath:path];
NSString *nextItem = [NSString string];
int i = 0;
while( (nextItem = [dirnum nextObject]))
{
NSString *filePath = [path stringByAppendingPathComponent:nextItem];
BOOL isDir = NO;
[[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDir];
if(NO == isDir) {
if([fileManager isReadableFileAtPath:filePath])
{
i++;
[filePaths appendFormat:#"%d)",i];
[filePaths appendString:nextItem];
[filePaths appendString:#"\n"];
}
}
}
NSString *format = [NSString stringWithFormat:#"Paths : %#", filePaths];
return format;
}
Related
I want make a zip file containing multiple documents, documents are taken from my Document Directory.
BOOL isDir=NO;
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSArray *subpaths;
for(int i=0; i<[arrdocument count]; i++)
{
NSString *toCompress = [arrdocument objectAtIndex:i];
NSString *pathToCompress = [documentsDirectory stringByAppendingPathComponent:toCompress];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:pathToCompress isDirectory:&isDir] && isDir){
subpaths = [fileManager subpathsAtPath:pathToCompress];
} else if ([fileManager fileExistsAtPath:pathToCompress]) {
subpaths = [NSArray arrayWithObject:pathToCompress];
}
NSString *zipFilePath = [documentsDirectory stringByAppendingPathComponent:#"myZipFileName2.zip"];
ZipArchive *za = [[ZipArchive alloc] init];
[za CreateZipFile2:zipFilePath];
if (isDir) {
for(NSString *path in subpaths){
NSString *fullPath = [pathToCompress stringByAppendingPathComponent:path];
if([fileManager fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir){
[za addFileToZip:fullPath newname:path];
}
}
} else {
[za addFileToZip:pathToCompress newname:toCompress];
}
}
But when I look at the zip file it shows only one document inside the zip file?
It seems like you recreate the zip file in each loop iteration. You should instead move the creation of the zip file out of the loop or just specify appending when you create the zip file like this:
[za CreateZipFile2:zipFilePath append:YES];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *zipFile = [documentsDirectory stringByAppendingPathComponent:#"compressed.zip"];
ZipArchive *zip = [[ZipArchive alloc] init];
BOOL result = [zip CreateZipFile2:zipFile];
if(result){
NSError *error;
NSArray *allFiles = arrdocument;
for(int index = 0; index<allFiles.count; index++){
id singleFileName = [allFiles objectAtIndex:index];
NSString *singleFilePath = [documentsDirectory stringByAppendingPathComponent:singleFileName];
[zip addFileToZip:singleFilePath newname:singleFileName];
}
[zip CloseZipFile2];
}else{
[self showErrorMessage:#"Unable to to create zip file. Please try again later" withTitle:#"Error"];
}
I need to sort 8145 objects (there may be more) for files and folders. (Tested on A8X).
First method.
for(NSString *filename in FilesList) //This method takes an average of 7.7 seconds.
{
fileExtension = (__bridge CFStringRef)[filename pathExtension];
fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
if ([[[[NSFileManager defaultManager] attributesOfItemAtPath:[FolderPath stringByAppendingPathComponent:filename] error:nil] fileType] isEqualToString:#"NSFileTypeDirectory"] && !UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:filename];
else
[OnlyFilesList addObject:filename];
}
Second method.
for(NSString *filename in FilesList) //This method takes an average of 2.9 seconds.
{
fileExtension = (__bridge CFStringRef)[filename pathExtension];
fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
[[NSFileManager defaultManager] fileExistsAtPath:[FolderPath stringByAppendingPathComponent:filename] isDirectory:&isDir];
if (isDir && !UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:filename];
else
[OnlyFilesList addObject:filename];
}
Do you know a faster way?
-----Update with add fastest method----- // 0.26 seconds for 8145 objects!
NSNumber *isDirectory;
NSError *error = nil;
NSString *name;
NSArray *FilesList = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:FolderPath] includingPropertiesForKeys:[NSArray arrayWithObjects:NSURLIsDirectoryKey,NSURLNameKey,nil] options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];
for (NSURL *url in FilesList)
{
[url getResourceValue:&name forKey:NSURLNameKey error:&error];
[url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:&error];
if ([isDirectory boolValue])
{
CFStringRef fileExtension = (__bridge CFStringRef)[name pathExtension];
CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
if (!UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:name];
else
[OnlyFilesList addObject:name];
}
else
[OnlyFilesList addObject:name];
}
Try using contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error::
NSURL *root = ... // the root URL to get the file list from
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *filesList = [fm contentsOfDirectoryAtURL:root includingPropertiesForKeys:#[ NSURLIsDirectoryKey, NSURLTypeIdentifierKey ] options:NSDirectoryEnumerationSkipsHiddenFiles error:&error];
if (dirURLs) {
for (NSURL *fileURL in filesList) {
NSString *filename = [[fileURL path] lastPathComponent];
NSNumber *isDir = nil;
[fileURL getResourceValue:&isDir forKey:NSURLIsDirectoryKey error:nil]
if ([isDir boolValue]) {
NSString *uti;
[fileURL getResourceValue:&uti forKey:NSURLTypeIdentifierKey error:nil];
if ([(__bridge NSString *)kUTTypeRTFD isEqualToString:uti]) {
[OnlyFilesList addObject:filename];
} else {
[OnlyFoldersList addObject:filename];
}
} else {
[OnlyFilesList addObject:filename];
}
}
} else {
NSLog(#"Unable to get list of files in %#: %#", root, error);
}
In the second method move fileExtension and fileUTI inside a test for isDir so that code does not run if the file is not potentially a directory.
Try this:
NSFileManager *fileManager = [NSFileManager defaultManager];
for(NSString *filename in FilesList) {
[fileManager fileExistsAtPath:[FolderPath stringByAppendingPathComponent:filename] isDirectory:&isDir];
if (isDir) {
CFStringRef fileExtension = (__bridge CFStringRef)[filename pathExtension];
CFStringRef fileUTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExtension, NULL);
if (!UTTypeConformsTo(fileUTI, kUTTypeRTFD))
[OnlyFolderList addObject:filename];
else
[OnlyFilesList addObject:filename];
}
else
[OnlyFilesList addObject:filename];
}
Try using the BSD API directly.
static BOOL cStringHasSuffix(const char *string, const char *suffix) {
unsigned long stringLength = strlen(string);
unsigned long suffixLength = strlen(suffix);
return stringLength >= suffixLength && memcmp(string + stringLength - suffixLength, suffix, suffixLength) == 0;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURL *url = [[NSBundle mainBundle] bundleURL];
NSMutableArray *folderNames = [NSMutableArray array];
NSMutableArray *fileNames = [NSMutableArray array];
const char *rtfdSuffix = ".rtfd";
DIR *dir = opendir(url.fileSystemRepresentation);
struct dirent *item;
while ((item = readdir(dir))) {
NSString *name = [NSString stringWithUTF8String:item->d_name];
if (item->d_type == 0) {
NSLog(#"unknown type for %#", name);
} else if (item->d_type == DT_DIR) {
if (cStringHasSuffix(item->d_name, rtfdSuffix)) {
[fileNames addObject:name];
} else {
[folderNames addObject:name];
}
} else if (item->d_type == DT_REG) {
[fileNames addObject:name];
} else {
NSLog(#"unexpected type %d for %#", item->d_type, name);
}
}
closedir(dir);
NSLog(#"fileNames = %#", fileNames);
NSLog(#"folderNames = %#", folderNames);
return YES;
}
I have used some ways to check MD5 after downloading files. But, it seems that checking too much files md5 always lead to memory warning or crash for low memory. Does someone have a good solution for this?
I have use method to check MD5 from Joel's Writings, and other methods from other posts, but all could not solve my problem.
NSInteger index = 0;
while (downloadQueue.count > 0) {
NSLog(#"%i files need to download.", downloadQueue.count);
NSLog(#"00: %u", [MenChecker get_free_memory]);
#autoreleasepool {
NSString *src = [downloadQueue objectAtIndex:index];
NSString *path = [self.storageRoot stringByAppendingPathComponent:[storageList objectAtIndex:index]];
NSString *md5 = [md5CheckList objectAtIndex:index];
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:path];
if (isExist) {
NSString *md5OfData = nil;
CFStringRef fileMD5Hash = FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
if (fileMD5Hash) {
md5OfData = (__bridge NSString *)fileMD5Hash;
CFRelease(fileMD5Hash);
}
if ([md5OfData isEqualToString:md5]) {
[downloadQueue removeObjectAtIndex:index];
[storageList removeObjectAtIndex:index];
[md5CheckList removeObjectAtIndex:index];
}
else {
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
ASIHTTPRequest *request_cover = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:src]];
[request_cover setDownloadDestinationPath:path];
[request_cover startSynchronous];
NSString *md5OfDataFile = nil;
CFStringRef dataFileMD5Hash = FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
if (dataFileMD5Hash) {
md5OfDataFile = (__bridge NSString *)dataFileMD5Hash;
CFRelease(dataFileMD5Hash);
}
if ([[NSFileManager defaultManager] fileExistsAtPath:path] && [md5OfDataFile isEqualToString:md5]) {
[downloadQueue removeObjectAtIndex:index];
[storageList removeObjectAtIndex:index];
[md5CheckList removeObjectAtIndex:index];
}
else {
index ++;
}
md5OfDataFile = nil;
}
md5OfData = nil;
}
else {
NSString *directory = [path stringByReplacingOccurrencesOfString:[NSString stringWithFormat:#"/%#", [path lastPathComponent]] withString:#""];
[[NSFileManager defaultManager] createDirectoryAtPath:directory withIntermediateDirectories:YES attributes:nil error:nil];
ASIHTTPRequest *request_cover = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:src]];
[request_cover setDownloadDestinationPath:path];
[request_cover startSynchronous];
request_cover = nil;
NSString *md5OfData = nil;
CFStringRef fileMD5Hash = FileMD5HashCreateWithPath((__bridge CFStringRef)path, FileHashDefaultChunkSizeForReadingData);
if (fileMD5Hash) {
md5OfData = (__bridge NSString *)fileMD5Hash;
CFRelease(fileMD5Hash);
}
if ([[NSFileManager defaultManager] fileExistsAtPath:path] && [md5OfData isEqualToString:md5]) {
[downloadQueue removeObjectAtIndex:index];
[storageList removeObjectAtIndex:index];
[md5CheckList removeObjectAtIndex:index];
}
else {
index ++;
}
md5OfData = nil;
}
if (index >= downloadQueue.count) {
index = 0;
}
}
I am working on zip and unzip object, and for that, I am using ziparchive classes ,I am able to zip files but problem occurs while unzipping of file ,following is my code
NSString *str1;
ZipArchive *za = [[ZipArchive alloc] init];
[za CreateZipFile2:zipFile];
NSLog(#"this is my whole new ipad%d",pictureArr.count);
[self calculation];
for (int i=0;i<[pictureArr count]; i++) {
NSString *str = [NSString stringWithFormat:#"%#",[pictureArr objectAtIndex:i]];
NSLog(#"This is my whole new ipad%#",[pictureArr objectAtIndex:i]);
[za addFileToZip:str newname:[pictureArr objectAtIndex:i]];
}
//NSString *textPath = [cachePath stringByAppendingPathComponent:#"text.txt"];
NSString *strUrl = [NSString stringWithString:path];
NSString *strunzip=[docspath stringByAppendingPathComponent:strUrl];
NSLog(#"This is my new file path for strXmlName%#",docspath);
[za addFileToZip:strUrl newname:strXmlName];
NSString *fileContent = [docspath stringByAppendingPathComponent:#"strXmlName.zip"];
NSLog(#"This is my final path for%#",fileContent);
NSString *updateURL = [[NSBundle mainBundle] pathForResource:fileContent ofType:#"zip" inDirectory:#"res"];
if ([za UnzipOpenFile:fileContent]) {
if ([za UnzipFileTo:docspath overWrite:NO]) {
NSLog(#"Archive unzip success");
[fileManager removeItemAtPath:docspath error:NULL];
}
else {
NSLog(#"Failure to unzip archive");
}
/*7405726724,9227669500-agile infoway
*/
}
else {
NSLog(#"Failure to open archive");
}
NSData *unzipData = [NSData dataWithContentsOfFile:fileContent];
fileManager = [NSFileManager defaultManager];
[fileManager createFileAtPath:docspath contents:unzipData attributes:nil];
NSLog(#"This is my file");
[za UnzipOpenFile:path];
BOOL success = [za CloseZipFile2];
NSLog(#"Zipped file with result %d",success);
but it directly goes out from if ([za UnzipOpenFile:fileContent]) i dont know why its happning,
what i have tried is this
and this
so please guide me
thanks
I want to retrieve in an array of the name of the files in Resources folder that have the .html extension. I have done this:
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Resources"];
NSError *error = nil;
NSArray *documentArray = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectory error:&error];
for (int i=0; i < [documentArray count] - 1; i++) {
NSLog(#"value %#", [documentArray objectAtIndex:i]);
}
But the for loop displays continously null. Anyone knows how can I get this task right? thank you
Don't use NSHomeDirectory. Use [[NSBundle mainBundle] resourcePath] to get path to app's resources.
Edited: here's your example code.
NSString *resPath = [[NSBundle mainBundle] resourcePath];
NSError *error = nil;
NSArray *filenames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:resPath error:&error];
if (!error)
{
for (NSString * filename in filenames)
{
NSString *extension = [filename pathExtension];
if ([extension isEqualToString:#"html"])
{
NSLog(#"%#", filename);
}
}
}