OS XでSwift/Cocoaを使用して一意の一時ファイルパスを取得する方法Cocoaはこのための関数を提供していないようです。一時ディレクトリのパスを返すNSTemporaryDirectory()
のみです。 BSD mktemp
関数を使用するには、引数として可変C文字列が必要です。
Swift以降のmkstemp()
を使用する方法は次のとおりです。 URL
メソッドは、URL
インスタンスとファイルシステムパスを表すC文字列との間の変換に使用されます。
// The template string:
let template = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("file.XXXXXX") as NSURL
// Fill buffer with a C string representing the local file system path.
var buffer = [Int8](repeating: 0, count: Int(PATH_MAX))
template.getFileSystemRepresentation(&buffer, maxLength: buffer.count)
// Create unique file name (and open file):
let fd = mkstemp(&buffer)
if fd != -1 {
// Create URL from file system string:
let url = URL(fileURLWithFileSystemRepresentation: buffer, isDirectory: false, relativeTo: nil)
print(url.path)
} else {
print("Error: " + String(cString: strerror(errno)))
}
Swift 2:の以前のコード
// The template string:
let template = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("file.XXXXXX")
// Fill buffer with a C string representing the local file system path.
var buffer = [Int8](count: Int(PATH_MAX), repeatedValue: 0)
template.getFileSystemRepresentation(&buffer, maxLength: buffer.count)
// Create unique file name (and open file):
let fd = mkstemp(&buffer)
if fd != -1 {
// Create URL from file system string:
let url = NSURL(fileURLWithFileSystemRepresentation: buffer, isDirectory: false, relativeToURL: nil)
print(url.path!)
} else {
print("Error: " + String(strerror(errno)))
}
Appleはpath-as-stringからNSURL
に移行しようとしています。 1つの方法を次に示します。
Swift 3:
let directory = NSTemporaryDirectory()
let fileName = NSUUID().uuidString
// This returns a URL? even though it is an NSURL class method
let fullURL = NSURL.fileURL(withPathComponents: [directory, fileName])
Swift 2:
let directory = NSTemporaryDirectory()
let fileName = NSUUID().UUIDString
let fullURL = NSURL.fileURLWithPathComponents([directory, fileName])
A Swift 3 IDベースのSwift 2回答 :
let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString)
GUID(グローバル一意識別子):
let directory :NSString = "directory"
let randomName = NSProcessInfo().globallyUniqueString
let path = directory.stringByAppendingPathComponent(randomName)
ディレクトリ/ 3B635E49-813A-4324-B4B8-56279B42BEAB-36687-0002D962615DAE5F
この記事のアイデアが好きです: NSTemporaryDirectory-NSHipster
これは、一時フォルダーにNSTemporaryDirectory()
を使用し、ProcessInfo.processInfo.globallyUniqueString
一意の文字列を生成します。
スウィフト4:
func uniqueTempFolderURL() -> URL
{
let folderName = ProcessInfo.processInfo.globallyUniqueString
return URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(folderName)
}
FileManager extension in Swift=一時ファイルのURLを取得します。必要に応じて、独自のファイル名と拡張子を渡すことができます。
public extension FileManager {
func temporaryFileURL(fileName: String = UUID().uuidString) -> URL? {
return URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(fileName)
}
}
使用法:
let tempURL = FileManager.default.temporaryFileURL()
let tempJPG = FileManager.default.temporaryFileURL(fileName: "temp.jpg")
boost :: filesystem :: unique_path() のようなものを探してここに来ました
そこで、この拡張機能をURLクラスに作成しました。
extension URL {
func appendingUniquePathComponent(pathExtension: String? = nil) -> URL {
var pathComponent = UUID().uuidString
if let pathExtension = pathExtension {
pathComponent += ".\(pathExtension)"
}
return appendingPathComponent(pathComponent)
}
}
let url0 = URL(fileURLWithPath: "/tmp/some/dir")
let url1 = url0.appendingUniquePathComponent(pathExtension: "jpg")
print("url1: \(url1)")
// url1: file:///tmp/some/dir/936324FF-EEDB-410E-AD09-E24D5EB4A24F.jpg
NSTemporaryDirectory()
は実際に現在のユーザーの一時ディレクトリパスを返しますが、 ドキュメント には次の警告が含まれています。
正しい一時ディレクトリを見つけるための推奨される方法については、
FileManager
メソッドurl(for:in:appropriateFor:create:)
を参照してください。
そのリンクに続いて、以下が表示されます。
このメソッドを使用して、新しい一時ディレクトリを作成できます。これを行うには、
directory
パラメーターに _FileManager.SearchPathDirectory.itemReplacementDirectory
_ を指定し、userDomainMask
パラメーターにdomain
を指定し、返されたURLのボリュームを決定するurl
パラメータのURL。たとえば、次のコードでは、_
/private/var/folders/d0/h37cw8ns3h1bfr_2gnwq2yyc0000gn/T/TemporaryItems/Untitled/
_という形式のパスを持つ新しい一時ディレクトリが作成されます。_let desktop = URL(fileURLWithPath: "/Users/jappleseed/Desktop/") do { let temporaryDirectory = try FileManager.default.url( for: .itemReplacementDirectory, in: .userDomainMask, appropriateFor: desktop, create: true ) print(temporaryDirectory) } catch { // Handle the error. }
_
(一時ディレクトリを作成する場合、create
パラメーターは無視されることに注意してください。)
それでは、これら2つのアプローチの違いは何ですか?さて、 Swift REPL から2つの異なるメソッドを呼び出すと、次のようになります。
_1> import Foundation
2> NSTemporaryDirectory()
$R0: String = "/var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/"
3> let desktop = URL(fileURLWithPath: "/Users/chris/Desktop/")
desktop: URL = "file:///Users/chris/Desktop/"
4> let temporaryDirectory = try FileManager.default.url(
5. for: .itemReplacementDirectory,
6. in: .userDomainMask,
7. appropriateFor: desktop,
8. create: true
9. )
temporaryDirectory: URL = "file:///var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/TemporaryItems/(A%20Document%20Being%20Saved%20By%20repl_Swift)/"
_
NSTemporaryDirectory()
は常にthe現在のユーザーの一時ディレクトリパスを返しますが、FileManager
のurl(for:appropriateFor:create)
は、呼び出されるたびにnew一時サブディレクトリを返します。たとえば、Swift REPL)からのurl(for:in:appropriateFor:create:)
の連続呼び出しによって返されるディレクトリは次のとおりです。
file:///var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/TemporaryItems/(A%20Document%20Being%20Saved%20By%20repl_Swift)/
file:///var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/TemporaryItems/(A%20Document%20Being%20Saved%20By%20repl_Swift%202)/
file:///var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/TemporaryItems/(A%20Document%20Being%20Saved%20By%20repl_Swift%203)/
そして、Swift Playground:
file:///var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/TemporaryItems/(A%20Document%20Being%20Saved%20By%20Xcode)/
file:///var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/TemporaryItems/(A%20Document%20Being%20Saved%20By%20Xcode%202)/
file:///var/folders/n_/0_9q7d2d1ls5v9kx599y_tj00000gn/T/TemporaryItems/(A%20Document%20Being%20Saved%20By%20Xcode%203)/
NSHipsterの一時ファイルに関する記事 は、FileManager
メソッドurl(for:in:appropriateFor:create:)
が、ファイルをより永続的な場所に移動するためにステージングするときに使用されることを示唆しているようです(上記の例のユーザーのデスクトップなど)、しかし、それが終わったときに自動的に削除される一意のサブディレクトリを取得するために使用できない理由がわかりません同じ一時ディレクトリに書き込む他のプロセスによって誤ってファイルが上書きされることを心配するため。