Skip to content

Instantly share code, notes, and snippets.

@gitbricho
Last active March 26, 2016 06:52
Show Gist options
  • Save gitbricho/897cee3859db3c384e1e to your computer and use it in GitHub Desktop.
Save gitbricho/897cee3859db3c384e1e to your computer and use it in GitHub Desktop.
ファイル操作
import Foundation
//#################
// ファイル操作機能.
//#################
protocol FileFunc {
func read() -> String
func write(output: String,
whenComplete: ((err: Bool, msg: String) -> Void))
func append(output: String,
whenComplete: ((err: Bool, msg: String) -> Void))
func delete(whenComplete: ((err: Bool, msg: String) -> Void))
func create(whenComplete: ((err: Bool, msg: String) -> Void))
}
/**
* アプリでファイル操作を行うためのユーティリティクラス.
* このクラスのインスタンスで操作できるのはインスタンス生成時に指定した
* パス以下のディレクトリとファイルのみとする。
* パスを指定しない場合は、ユーザーホームが自動的に設定される。
*/
public class FilePath: NSObject, FileFunc {
// MARK:静的変数
public static var _UserHome: FilePath {
return FilePath(fullPath: NSHomeDirectory())
}
// MARK:プロパティ
//- このノードのパス
var zFullPath: String
//- このノードがディレクトリなら子ノード配列を返す
lazy var zFiles: [FilePath]? = {
let mn = NSFileManager.defaultManager()
let fullPath:String = self.zFullPath as String
var files: [FilePath] = []
//このノードが存在し、かつディレクトリの場合はディレクトリの内容を返す
if (self.zIsDir) {
let contents: [AnyObject]?
do {
contents = try
mn.contentsOfDirectoryAtPath(fullPath)
} catch _ {
contents = nil
}
if let cts = contents as? [String] {
for ct in cts {
let absPath = "\(self.zFullPath)/\(ct)"
files.append(FilePath(fullPath: absPath))
}
}
return files
} else {
return nil
}
}()
//- 属性
public var zAttrib: [String : AnyObject] {
let mn = NSFileManager.defaultManager()
return (try? mn.attributesOfItemAtPath(zFullPath)) ?? [:]
}
//- ファイル作成日
public var zCreateDate: NSDate? {
return zAttrib[NSFileCreationDate] as? NSDate
}
//- ファイル更新日
public var zUpdateDate: NSDate? {
return zAttrib[NSFileModificationDate] as? NSDate
}
//- 拡張子が非表示かどうか
public var zHidden: Bool? {
if let value = zAttrib[NSFileExtensionHidden] as? NSNumber {
return value.boolValue
}
return nil
}
/// The POSIX permissions of the file at the path.
public var zPosixPermissions: Int16? {
if let value = zAttrib[NSFilePosixPermissions] as? NSNumber {
return value.shortValue
}
return nil
}
//- ファイルサイズ
public var zSize: UInt64? {
if let value = zAttrib[NSFileSize] as? NSNumber {
return value.unsignedLongLongValue
}
return nil
}
//- 拡張子
public var zExtension: String {
get {
return (zFullPath as NSString).pathExtension
}
}
//- 親パス
public var zParentPath: FilePath {
return FilePath(fullPath: (zFullPath as NSString).stringByDeletingLastPathComponent)
}
//- ファイル名
public var zFileName: String {
return (zFullPath as NSString).lastPathComponent
}
//- ディレクトリか
public var zIsDir: Bool {
var isDir: ObjCBool = false
let mn = NSFileManager.defaultManager()
return mn.fileExistsAtPath(
zFullPath, isDirectory: &isDir)
? isDir.boolValue : false
}
public override var description: String {
return "FileNode:\(zFullPath)"
}
// MARK:イニシャライザ
init(fullPath: NSString) {
self.zFullPath = fullPath as String
}
//-- 子ノードの数を返す。0を返す場合このノードはディレクトリではない。
public func filesCount() -> Int {
guard let files = self.zFiles
else { return 0 }
return files.count
}
//-- 子ノード配列を持つ場合、指定位置の子ノードを返す。
public func file(n: Int) -> FilePath? {
guard let files = self.zFiles
else { return nil }
return files[n]
}
// MARK: FileFuncの実装
/// ファイルを読む.
public func read() -> String {
do {
let l入力内容 = try NSString(
contentsOfFile: self.zFullPath,
encoding: NSUTF8StringEncoding )
return l入力内容 as String
} catch let error as NSError {
return error.localizedDescription
}
}
/// ファイルへ文字列(output)を出力する.
public func write(output: String,
whenComplete: ((err: Bool, msg: String) -> Void)) {
do{
try output.writeToFile(
self.zFullPath,
atomically: true,
encoding: NSUTF8StringEncoding)
whenComplete(err: false,
msg: "\(zFullPath):出力成功")
} catch let error as NSError {
whenComplete(err: true,
msg: error.localizedDescription)
}
}
public func append(output: String,
whenComplete: ((err: Bool, msg: String) -> Void)) {
//
}
/// ファイルを作成する.
public func create(
whenComplete: ((err: Bool, msg: String) -> Void)) {
let mn = NSFileManager.defaultManager()
if !self.zIsDir {
//ファイルを作成
if mn.createFileAtPath(zFullPath,
contents: nil,
attributes: nil) {
whenComplete(err: false,
msg: "\(zFullPath):作成成功")
} else {
whenComplete(err: true,
msg: "\(zFullPath):作成失敗")
}
} else {
//ディレクトリを作成
do {
try mn.createDirectoryAtPath(zFullPath,
withIntermediateDirectories: true,
attributes: nil)
whenComplete(err: false,
msg: "\(zFullPath):作成成功")
} catch let error as NSError {
whenComplete(err: true,
msg: error.localizedDescription)
}
}
}
/// ファイルを削除する.
public func delete(
whenComplete: ((err: Bool, msg: String) -> Void)) {
let mn = NSFileManager.defaultManager()
if !self.zIsDir {
//ファイルを削除
do {
try mn.removeItemAtPath(self.zFullPath)
whenComplete(err: false,
msg: "\(zFullPath):削除成功")
} catch let error as NSError {
whenComplete(err: true,
msg: error.localizedDescription)
}
} else {
//ディレクトリを削除
}
}
}
import Cocoa
//################################
// ファイル情報を保持する.
//################################
struct FileInfo {
var zFileName:String = ""
var zIsDir:Bool = false
var zFileSize:UInt64
var zFileUpdateDate:NSDate
}
//#################################
// テーブルビューにファイル情報を表示する.
//#################################
class ViewController: NSViewController,
NSTableViewDataSource,
NSTableViewDelegate {
//MARK:プロパティ
@IBOutlet weak var tableView: NSTableView!
//作業フォルダ
var zWorkDir: String = ""
//作業フォルダ以下のファイル情報を保持する配列
var zFiles: [FileInfo] = []
//デフォルトの作業フォルダ
let documentsPath = NSSearchPathForDirectoriesInDomains(
.DocumentDirectory, .UserDomainMask, true)[0] as String
//MARK:ライフサイクル
override func viewDidLoad() {
super.viewDidLoad()
zWorkDir = FilePath._UserHome.zFullPath
+ "/_wsp/_test"
getFiles(zWorkDir)
tableView.setDataSource(self)
tableView.setDelegate(self)
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
//MARK:データソース
//テーブルのデータの行数を返す
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return zFiles.count
}
//行番号(row), 列タイトルに対応するセルの表示内容を返す.
func tableView(aTableView: NSTableView,
objectValueForTableColumn aTableColumn: NSTableColumn?,
row rowIndex: Int) -> AnyObject? {
var selData = "";
if (rowIndex < zFiles.count) {
let f:FileInfo = zFiles[rowIndex]
switch (aTableColumn?.title)! {
case "ファイル名":
selData = f.zFileName
case "タイプ":
selData = f.zIsDir
? "ディレクトリ" : "ファイル"
case "更新日":
selData = "\(f.zFileUpdateDate)"
case "サイズ":
selData = "\(f.zFileSize)"
default:
break
}
}
return selData
}
//MARK: デリゲート
//テーブルビューの選択行が変わった場合.
func tableViewSelectionDidChange(aNotification: NSNotification) {
if let selFile = fileInfoOfSelectRow() {
print(selFile.zFileName)
}
}
//MARK:アクション
....
//MARK:ヘルパーメソッド
/// 指定した作業フォルダ以下のファイルを取得
func getFiles(workDir: String) {
let dirPath = FilePath(fullPath: workDir)
print("docpath:\(documentsPath)")
print("フルパス:\(dirPath.zFullPath)")
print("ファイル名:\(dirPath.zFileName)")
print("親パス:\(dirPath.zParentPath.zFullPath)")
for path in dirPath.zFiles! {
zFiles.append(FileInfo(
zFileName: path.zFileName,
zIsDir: path.zIsDir,
zFileSize: path.zSize!,
zFileUpdateDate: path.zUpdateDate!))
}
}
/// 完了時処理
func fCompletionHandler(err: Bool, msg: String) -> Void {
if err {
print("エラー: \(msg)")
} else {
print("\(msg)")
}
}
/// 選択行のファイル情報を返す
func fileInfoOfSelectRow() -> FileInfo? {
let selRow = self.tableView.selectedRow
if selRow >= 0 && selRow < self.zFiles.count {
return self.zFiles[selRow]
}
return nil
}
}
...
/// ユーザーが指定した名前でファイルを作成する.
@IBAction func createFile(sender: AnyObject) {
let savePanel = NSSavePanel()
savePanel.nameFieldStringValue = "newFile.txt"
func modalCompletionHandler(modalResponse: NSModalResponse) {
if modalResponse == NSFileHandlingPanelOKButton {
let createPath = savePanel.URL!.relativePath!
print("作成URL=\(createPath)")
//新規ファイルの作成
let filePath = FilePath(fullPath: createPath)
filePath.write("line01\nline02\nline03",
whenComplete: fCompletionHandler)
}
}
if let sheetParent = view.window {
savePanel.beginSheetModalForWindow(sheetParent, completionHandler: modalCompletionHandler)
} else {
savePanel.beginWithCompletionHandler(modalCompletionHandler)
}
}
...
...
/// 作業ディレクトリを変更する.
@IBAction func changeWorkDir(sender: AnyObject) {
// パスのトップディレクトリを選択するために`NSOpenPanel`を開く.
let openPanel = NSOpenPanel()
//初期ディレクトリはユーザーホーム
openPanel.directoryURL = NSURL(string: FilePath._UserHome.zFullPath)
//ディレクトリ選択は有効(デフォルト:無効)
openPanel.canChooseDirectories = true
//ディレクトリ作成は無効(デフォルト:無効)
openPanel.canCreateDirectories = false
//ファイル選択は無効(デフォルト:有効)
openPanel.canChooseFiles = false
//複数選択は無効(デフォルト:無効)
openPanel.allowsMultipleSelection = false
//選択可能なファイルタイプ: 今回は使わない
//openPanel.allowedFileTypes = ["txt", "pdf"]
openPanel.showsHiddenFiles = false
openPanel.showsResizeIndicator = false
openPanel.title = "作業フォルダの選択"
func modalCompletionHandler(modalResponse: NSModalResponse) {
// "OK"が押されたかチェック.
if modalResponse == NSFileHandlingPanelOKButton {
// 全選択 URL に対してSFileを作成して、zFiles へ追加.
print("選択URL=\(openPanel.URL!.relativePath)")
zFiles = []
getFiles(openPanel.URL!.relativePath!)
tableView.reloadData()
}
}
if let sheetParent = view.window {
openPanel.beginSheetModalForWindow(sheetParent, completionHandler: modalCompletionHandler)
} else {
openPanel.beginWithCompletionHandler(modalCompletionHandler)
}
}
...
...
/// テーブルビューのカレント選択行の内容を読む.
@IBAction func readSelectFile(sender: AnyObject) {
if let selFile = fileInfoOfSelectRow() {
if !selFile.zIsDir {
let readPath = zWorkDir + "/" + selFile.zFileName
let filePath = FilePath(fullPath: readPath)
let c = filePath.read()
print("--------------")
print(c)
}
}
}
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment