2016-04-14 55 views
1

從C++訪問OS X上的標準目錄(如~/Library/Application Support~/Library/Preferences)的現代標準規範方法是什麼?使用C++在OS X上訪問標準目錄

我見過使用CoreServices提及,但它也提到,它過時,我無法找到,讓我做的不僅僅是粘貼代碼的文檔。

我我發現提及使用Objective C++,但大多數有關該選項的信息都圍繞從Objective C調用C++代碼展開,並且Apple的文檔似乎相當稀少,或者至少我沒有成功找到它。

回答

1

看一看下面的技術問答&一個,解決環境中的波浪線擴展,你不會想在NS命名空間拉: https://developer.apple.com/library/mac/qa/qa1549/_index.html

我還沒有遇到過內置的CoreFoundation調用類似於NSString的expandTildeAtPath。至於你提到的CoreServices例子,其中包括FsRefs。這些是舊的Carbon調用和對象來處理系統文件。這些已被棄用,而不是CoreFoundation。

+0

謝謝你的迴應,而工作,它的inelegance乾脆把我趕走。我決定使用Objective C++,它幾乎允許我在儘可能不使用C++的情況下使用此C++ API。儘管我仍然不確定'[NSFileManager URLsForDirectory:inDomains]'還是使用'NSURL'是最好的(我現在使用的是'NSFileManager'),但至少它使用簡單的代碼而不是Core Foundation的解決方法。 – Chuck

1

那麼,有一個鮮爲人知的NSSystemDirectories.h(在/usr/include/NSSystemDirectories.h)標題已存在於每個版本的OS X我檢查一直回到OS X 10.3。它是libc的一部分:http://opensource.apple.com//source/Libc/Libc-825.40.1/include/NSSystemDirectories.h

這提供了一個C API,儘管創建一個Objective-C++包裝並不困難:創建一個純C++接口並在實現中使用Objective-C。

FolderManager.h:

#include <stdio.h> 
namespace fm { 
    enum { 
     NSApplicationDirectory = 1, 
     NSDemoApplicationDirectory, 
     NSDeveloperApplicationDirectory, 
     NSAdminApplicationDirectory, 
     NSLibraryDirectory, 
     NSDeveloperDirectory, 
     NSUserDirectory, 
     NSDocumentationDirectory, 
     NSDocumentDirectory, 
     NSCoreServiceDirectory, 
     NSAutosavedInformationDirectory = 11, 
     NSDesktopDirectory = 12, 
     NSCachesDirectory = 13, 
     NSApplicationSupportDirectory = 14, 
     NSDownloadsDirectory = 15, 
     NSInputMethodsDirectory = 16, 
     NSMoviesDirectory = 17, 
     NSMusicDirectory = 18, 
     NSPicturesDirectory = 19, 
     NSPrinterDescriptionDirectory = 20, 
     NSSharedPublicDirectory = 21, 
     NSPreferencePanesDirectory = 22, 
     NSApplicationScriptsDirectory = 23, 
     NSItemReplacementDirectory = 99, 
     NSAllApplicationsDirectory = 100, 
     NSAllLibrariesDirectory = 101, 
     NSTrashDirectory = 102 
    }; 
    typedef unsigned long SearchPathDirectory; 

    enum { 
     NSUserDomainMask = 1,  // user's home directory --- place to install user's personal items (~) 
     NSLocalDomainMask = 2,  // local to the current machine --- place to install items available to everyone on this machine (/Library) 
     NSNetworkDomainMask = 4, // publically available location in the local area network --- place to install items available on the network (/Network) 
     NSSystemDomainMask = 8,  // provided by Apple, unmodifiable (/System) 
     NSAllDomainsMask = 0x0ffff // all domains: all of the above and future items 
    }; 
    typedef unsigned long SearchPathDomainMask; 

    class FolderManager { 
     public: 

     FolderManager(); 
     ~FolderManager(); 

     const char *pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask); 
     const char *pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, SearchPathDomainMask domainMask, const char *itemPath, bool create = false); 

     private: 
      void *m_autoreleasePool; 
    }; 
}; 

FolderManager。 毫米(注意擴展名)

#include "FolderManager.h" 
#import <Foundation/Foundation.h> 

using namespace fm; 

FolderManager::FolderManager() { 
    m_autoreleasePool = [[NSAutoreleasePool alloc] init]; 
} 

FolderManager::~FolderManager() { 
    [(NSAutoreleasePool *)m_autoreleasePool release]; 
} 

const char * FolderManager::pathForDirectory(SearchPathDirectory directory, SearchPathDomainMask domainMask) { 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSArray *URLs = [fileManager URLsForDirectory:(NSSearchPathDirectory)directory inDomains:domainMask]; 
    if (URLs.count == 0) return NULL; 

    NSURL *URL = [URLs objectAtIndex:0]; 
    NSString *path = URL.path; 

    // `fileSystemRepresentation` on an `NSString` gives a path suitable for POSIX APIs 
    return path.fileSystemRepresentation; 
} 

const char * FolderManager::pathForDirectoryAppropriateForItemAtPath(SearchPathDirectory directory, 
SearchPathDomainMask domainMask, const char *itemPath, bool create) { 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSString *nsPath = [fileManager stringWithFileSystemRepresentation:itemPath length:strlen(itemPath)]; 
    NSURL *itemURL = (nsPath ? [NSURL fileURLWithPath:nsPath] : nil); 

    NSURL *URL = [fileManager URLForDirectory:(NSSearchPathDirectory)directory 
         inDomain:domainMask 
       appropriateForURL:itemURL 
         create:create error:NULL]; 
    return URL.path.fileSystemRepresentation; 
} 

注意,這不自動引用編譯計數啓用(或至少,這就是我如何使用它,它是可能的,它也將與ARC工作,但我沒有測試過)。分別在構造函數和析構函數中創建並釋放NSAutoreleasePool非常重要,否則,您可能會在控制檯中獲得內存泄漏和警告(除非已在其他地方爲您創建了NSAutoreleasePool)**。

要使用它,像這樣:

int main(int argc, const char * argv[]) { 

    char *folderPath = NULL; 
    FolderManager folderManager; 
    folderPath = (char *)folderManager.pathForDirectory(NSApplicationSupportDirectory, NSUserDomainMask); 
    printf("folderPath == %s\n", folderPath); 

    folderPath = (char *)folderManager.pathForDirectory(NSApplicationSupportDirectory, NSLocalDomainMask); 
    printf("folderPath == %s\n", folderPath); 

    folderPath = (char *)folderManager.pathForDirectory(NSTrashDirectory, NSAllDomainsMask); 
    printf("folderPath == %s\n", folderPath); 

    if (argc > 1) { 
     folderPath = (char *)folderManager.pathForDirectoryAppropriateForItemAtPath(NSTrashDirectory, NSAllDomainsMask, argv[1]); 
     printf("folderPath == %s\n", folderPath); 

     folderPath = (char *)folderManager.pathForDirectoryAppropriateForItemAtPath(NSItemReplacementDirectory, NSUserDomainMask, argv[1], true); 
     printf("folderPath == %s\n", folderPath); 
    } 

    return 0; 
} 

當我在我的機器上運行此,它傳遞的/Volumes/Untitled3/folder/testFile.chm一個參數,它會輸出如下:

folderPath == /Users/mdouma46/Library/Application Support 
folderPath == /Library/Application Support 
folderPath == /Users/mdouma46/.Trash 
folderPath == /Volumes/Untitled 3/.Trashes/501 
folderPath == /Volumes/Untitled 3/.TemporaryItems/folders.501/TemporaryItems/(A Document Being Saved By findFolder) 

**關於關於NSAutoreleasePool的重要性的內存管理評論:我在OS X Yosemite,Xcode 7.2.1中通過評論創建NSAutoreleasePool對此進行了測試,並且在我的生活中,我無法將任何錯誤記錄到控制檯,所以我不確定這是怎麼回事。

我期待的是當我在OS X 10的Xcode 3.2.6中編譯它時得到的結果。6:

findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x10010c6d0 of class NSCFArray autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x10010c820 of class NSCFString autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111540 of class NSCFString autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111710 of class NSPathStore2 autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111770 of class NSPathStore2 autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111a20 of class NSCFArray autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111a60 of class NSCFArray autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111d10 of class NSCFString autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111ac0 of class NSURL autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111c20 of class NSCFArray autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111de0 of class NSCFString autoreleased with no pool in place - just leaking 
findFolder[300] *** __NSAutoreleaseNoPool(): Object 0x100111cb0 of class NSConcreteData autoreleased with no pool in place - just leaking 
folderPath == /Users/mdouma46/Library/Application Support 

這是因爲許多Objective-C的呼叫的返回自動釋放物體:NSFileManagerURLsForDirectory:inDomain:返回NSURL秒的自動釋放的陣列。調用NSURLpath方法返回(創建)自動釋放NSString S(實際上,在NSPathStore2私有子類),等等

+0

我不知道這是否是另一個問題,但是當你在你的類實例中調用'pathForDirectory'時,爲什麼autorelease池會隱式地用於任何分配? – blackirishman

相關問題