web-dev-qa-db-ja.com

swiftを使用した一時ファイルパス

OS XでSwift/Cocoaを使用して一意の一時ファイルパスを取得する方法Cocoaはこのための関数を提供していないようです。一時ディレクトリのパスを返すNSTemporaryDirectory()のみです。 BSD mktemp関数を使用するには、引数として可変C文字列が必要です。

18
tmlen

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)))
}
22
Martin R

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])
30
Code Different

A Swift 3 IDベースのSwift 2回答

let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString)
5
mz2

GUID(グローバル一意識別子):

let directory :NSString = "directory"
let randomName = NSProcessInfo().globallyUniqueString
let path = directory.stringByAppendingPathComponent(randomName)

ディレクトリ/ 3B635E49-813A-4324-B4B8-56279B42BEAB-36687-0002D962615DAE5F

4
zaph

この記事のアイデアが好きです: NSTemporaryDirectory-NSHipster

これは、一時フォルダーにNSTemporaryDirectory()を使用し、ProcessInfo.processInfo.globallyUniqueString一意の文字列を生成します。

スウィフト4:

func uniqueTempFolderURL() -> URL
{
    let folderName = ProcessInfo.processInfo.globallyUniqueString
    return URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(folderName)
}
3
palme

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")
1
boherna

Swift3

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
1
neoneye

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現在のユーザーの一時ディレクトリパスを返しますが、FileManagerurl(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:)が、ファイルをより永続的な場所に移動するためにステージングするときに使用されることを示唆しているようです(上記の例のユーザーのデスクトップなど)、しかし、それが終わったときに自動的に削除される一意のサブディレクトリを取得するために使用できない理由がわかりません同じ一時ディレクトリに書き込む他のプロセスによって誤ってファイルが上書きされることを心配するため。

0
Chris Frederick