NSFileManager與沙盒操作
前言:iOS的沙盒機(jī)制,應(yīng)用只能訪問自己應(yīng)用目錄下的文件。iOS不像android,沒有SD卡概念,不能直接訪問圖像、視頻等內(nèi)容。iOS應(yīng)用產(chǎn)生的內(nèi)容,如圖像、文件、緩存內(nèi)容等都必須存儲在自己的沙盒內(nèi)。
常識:默認(rèn)情況下,每個(gè)沙盒含有3個(gè)文件夾:Documents, Library 和 tmp。Library包含Caches、Preferences目錄。
- Documents:蘋果建議將程序創(chuàng)建產(chǎn)生的文件以及應(yīng)用瀏覽產(chǎn)生的文件數(shù)據(jù)保存在該目錄下,iTunes備份和恢復(fù)的時(shí)候會包括此目錄
- Library:存儲程序的默認(rèn)設(shè)置或其它狀態(tài)信息;
- Library/Caches:存放緩存文件,保存應(yīng)用的持久化數(shù)據(jù),用于應(yīng)用升級或者應(yīng)用關(guān)閉后的數(shù)據(jù)保存,不會被itunes同步,所以為了減少同步的時(shí)間,可以考慮將一些比較大的文件而又不需要備份的文件放到這個(gè)目錄下。
- Library/Preference:保存應(yīng)用的所有偏好設(shè)置,IOS的Settings應(yīng)用會在該目錄中查找應(yīng)用的設(shè)置信息。
- tmp:提供一個(gè)即時(shí)創(chuàng)建臨時(shí)文件的地方,但不需要持久化,在應(yīng)用關(guān)閉后,該目錄下的數(shù)據(jù)將刪除,也可能系統(tǒng)在程序不運(yùn)行的時(shí)候清除。
接下來直接用代碼詮釋各種方法
- 各種目錄或者文件操作方法都封裝在viewDidLoad方法里面。
import UIKit
class ViewController: UIViewController {
let fileManager = NSFileManager.defaultManager()
let fileManager2 = NSFileManager()
override func viewDidLoad() {
super.viewDidLoad()
getDocumentPath()
getLibraryPath()
getCachePath()
getTempPath()
creatDirectory()
creatFile()
fileIsExist()
item操作()
readFile()
}
- 獲取Document路徑
func getDocumentPath(){
// 第一種獲取路徑方式
let HomePath = NSHomeDirectory()
print(HomePath)
let docPATH = HomePath + "/Documents" //cache 和library也可這樣拼接
print(docPATH)
// 第二種獲取路徑方式
let pathArr = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let documentPath = pathArr[0] as String
print(documentPath)
// 第三種獲取路徑方式
let urls = fileManager.URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask) as [NSURL]
if urls.count > 0{
print("--------\(urls[0])")
print("--------\(urls)")
}
// 第四種獲取路徑方式
do{
let url = try fileManager.URLForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomain: NSSearchPathDomainMask.UserDomainMask, appropriateForURL: nil, create: false)
print("--------\(url)")
}catch{
}
}
//上面兩個(gè)方法URLsForDirectory和URLForDirectory區(qū)別在于URLForDirectory還可以創(chuàng)建臨時(shí)目錄
- 獲取Library,Cache,Temp路徑
func getLibraryPath(){
let libtraryPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as String
print(libtraryPath)
}
func getCachePath(){
let cachePath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.CachesDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as String
print(cachePath)
}
func getTempPath(){
let tempPath = NSTemporaryDirectory()
print(tempPath)
let homePath = NSHomeDirectory()
let tempPath1 = homePath + "/tmp/"
print(tempPath1)
}
- 創(chuàng)建目錄
func creatDirectory()->String{
let documentPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0] as String
//如果轉(zhuǎn)成string,則可以直接用 + “/grandre”
let documentPathGrandre = (documentPath as NSString).stringByAppendingPathComponent("/grandre")
let documentPath2 = documentPath + "/grandre1/grandre2"
//withIntermediateDirectories 設(shè)置為true, 代表中間所有的路徑目錄如果不存在,都會創(chuàng)建
do{
try NSFileManager.defaultManager().createDirectoryAtPath(documentPathGrandre, withIntermediateDirectories: true, attributes: nil)
try NSFileManager.defaultManager().createDirectoryAtPath(documentPath2, withIntermediateDirectories: true, attributes: nil)
}catch{
print("創(chuàng)建目錄出錯(cuò)")
}
return documentPath2
}
- 創(chuàng)建文件
func creatFile(){
// 創(chuàng)建file第一種方式。通過寫入content來創(chuàng)建新文件。
let filePath = creatDirectory() + "/gr.text"
let content = "hello grandre"
do{
try content.writeToFile(filePath, atomically: true, encoding: NSUTF8StringEncoding)
}catch{
print("創(chuàng)建文件失敗")
}
// 創(chuàng)建file第二種方式。
let filePath2 = creatDirectory() + "/gr2.text"
let result = NSFileManager.defaultManager().createFileAtPath(filePath2, contents: nil, attributes: nil)
if result{
print("success creat file ")
}else{
print("error creat file")
}
}
- 判斷文件或者目錄是否存在
func fileIsExist(){
//用來判斷文件或者目錄是否存在
if fileManager.fileExistsAtPath(creatDirectory() + "/gr2.text"){
print("存在/gr2.text")
}
if fileManager.fileExistsAtPath(creatDirectory()){
print("存在目錄\(creatDirectory())")
}
}
- 目錄或者文件的移動,復(fù)制,刪除操作。
func item操作(){
//移動目錄,dest路徑中必須包含目錄名,當(dāng)然順便可以更改目錄名。
let documentsUrl = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let destUrl = documentsUrl as String + "/grandre2"
do{
try fileManager.moveItemAtPath(creatDirectory(), toPath: destUrl)
}catch{
print("move directory error")
}
//移動文件,dest路徑中必須包含文件名,當(dāng)然順便可以更改文件名。
do{
try fileManager.moveItemAtPath(destUrl+"/gr.text", toPath: documentsUrl as String + "/grandre1/gr1.text")
}catch{
print("move file error")
}
//復(fù)制目錄,也可更名
do{
try fileManager.copyItemAtPath(documentsUrl as String + "/grandre1", toPath: documentsUrl as String + "/grandre3")
}catch{
print("copy directory error")
}
do{
try fileManager.copyItemAtPath(documentsUrl as String + "/grandre1", toPath: documentsUrl as String + "/grandre3/grandre1")
}catch{
print("copy directory error")
}
//復(fù)制文件,也可更名
do{
try fileManager.copyItemAtPath(documentsUrl as String + "/grandre1/gr1.text", toPath: documentsUrl as String + "/grandre/gr1.text")
}catch{
print("copy file error")
}
//刪除指定item(目錄或者文件)
try?fileManager.removeItemAtPath(documentsUrl+"/grandre3/grandre1")
- 遍歷文件或者目錄
//獲取指定路徑下的所有目錄和文件,遞歸,深度。也即是下一級的子目錄子文件也會被列出來。
let itemGetArr1 = fileManager.subpathsAtPath(documentsUrl)
print(itemGetArr1)
let itemGetArr2 = try? fileManager.subpathsOfDirectoryAtPath(documentsUrl)
print(itemGetArr2)
//只獲取指定目錄下的目錄。而且非遞歸。淺度。
let itemGetArr3 = try? fileManager.contentsOfDirectoryAtPath(documentsUrl)
print(itemGetArr3)
//獲取指定目錄下的所有文件和目錄,遞歸,深度。返回的是NSDirectoryEnumerator。
let itemGetArr4 = fileManager.enumeratorAtPath(documentsUrl)
for i in itemGetArr4!{
print(i)
}
- 獲取目錄或者文件的屬性
//獲取指定item(目錄或者文件)的屬性。
let itemAttributes = try?fileManager.attributesOfItemAtPath(documentsUrl)
print(itemAttributes)
let itemAttributes1 = try?fileManager.attributesOfItemAtPath(documentsUrl+"/grandre/gr1.text")
print(itemAttributes1)
- 比較兩個(gè)文件是否相同
//比較兩個(gè)文件是否相同
if fileManager.contentsEqualAtPath(documentsUrl+"/grandre1/gr1.text", andPath: documentsUrl+"/grandre3/gr1.text"){
NSLog("two files are the same")
}
}
- 讀取文件內(nèi)容
func readFile(){
//只能讀取文件的內(nèi)容,不能讀取目錄的內(nèi)容
//第一種讀取方式
let documentsUrl = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
do{
let content = try?NSString(contentsOfFile: documentsUrl + "/grandre1/gr1.text", encoding: NSUTF8StringEncoding)
print(content)
}catch{
print("read file error")
}
//第二種讀取方式
let content1 = fileManager.contentsAtPath(documentsUrl + "/grandre1/gr1.text")
let result1 = NSString(data: content1!, encoding: NSUTF8StringEncoding)
print(result1)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
- 其他常用方法
-(NSString *)currentDirectoryPath 獲取當(dāng)前目錄
-(BOOL)changeCurrentDirectoryPath:path 更改當(dāng)前目錄
//常用路徑工具方法
-(NSString *) pathWithComponents:components 根據(jù)components中元素構(gòu)造有效路徑
-(NSArray *)pathComponents 析構(gòu)路徑,獲取路徑的各個(gè)部分
-(NSString *)lastPathComponent 提取路徑的最后一個(gè)組成部分
-(NSString *)pathExtension 路徑擴(kuò)展名
-(NSString *)stringByAppendingPathComponent:path 將path添加到現(xiàn)有路徑末尾
-(NSString *)stringByAppendingPathExtension:ext 將拓展名添加的路徑最后一個(gè)組成部分
-(NSString *)stringByDeletingPathComponent 刪除路徑的最后一個(gè)部分
-(NSString *)stringByDeletingPathExtension 刪除路徑的最后一個(gè)部分 的擴(kuò)展名
-(NSString *)stringByExpandingTildeInPath 將路徑中的代字符擴(kuò)展成用戶主目錄(~)或指定用戶主目錄(~user)
-(NSString *)stringByResolvingSymlinksInPath 嘗試解析路徑中的符號鏈接
-(NSString *)stringByStandardizingPath 通過嘗試解析~、..、.、和符號鏈接來標(biāo)準(zhǔn)化路徑