2017-11-12 4 views
3

は、次のコードスニペットを考えてみましょう:cString(:.utf8を使用)とwithUnsafeFileSystemRepresentation(_ :)はどのようにお互いに違いますか?

let url = FileManager.default.homeDirectoryForCurrentUser 

let cString1 = url.absoluteString.cString(using: .utf8) 

let cString2 = url.withUnsafeFileSystemRepresentation { $0 } 

は、我々はcString1cString2が等しいC文字列であることを期待することはできますか?

withUnsafeFileSystemRepresentation(_:)のドキュメントに記載されているように、Swift文字列をUTF8エンコーディングのC文字列に変換しています。それはまさにcString(using: .utf8)のことと同じです。

両方ともSwift文字列をタイプUnsafePointer<Int8>?に変換します。

のみXcodeはCCharInt8の型の別名である[CChar]?としてcString(using:)の戻り型が表示されています。またスウィフトアレイは私が知る限りUnsafePointerに渡すことができます。

ほとんどの場合、私はちょうどcString(using: .utf8)を使用していますが、何か問題はありません。何らかの理由でwithUnsafeFileSystemRepresentation(_:)を使用する必要があるまれなケースがあります。そうでなければ、C関数は文字列を認識しません。

私はここで何が違いますか? Apple File System Guide FAQから

答えて

3

ファイル名に(iOSの10.3.0について、10.3.1および10.3.2)不一致Unicode正規化とあなたのコード内のバグを導入することを避けるために、次の操作を行います。

  • ファイルシステムとやりとりをするときに、NSFileManagerやNSURLなどの高レベルFoundation APIを使用します。
  • NSURLオブジェクトのfileSystemRepresentationプロパティは、POSIX open(2)などの低レベルファイルシステムAPIを使用してファイルを作成して開くとき、またはファイルシステムからファイル名を外部に格納するときに使用します。

のでwithUnsafeFileSystemRepresentation()はパス はPOSIXコールに渡された場合、 getxattr()unlink()、などopen()stat()が必要...と保証されたシステムコールの正しいUnicodeの 正規形創造された。

簡単な例(それが存在する場合、エラーを無視して、ファイルを削除):

url.withUnsafeFileSystemRepresentation { 
    _ = unlink($0) 
} 

を参照してくださいWrite extend file attributes swift example "本物" は、例えば。

let cString2 = url.withUnsafeFileSystemRepresentation { $0 } 

は、ブロックのコンテキスト外でC文字列が有効でないため無効です。

はここで2つのAPIが 異なるC文字列を与えることができることを実証例です。

let path = "Café".precomposedStringWithCanonicalMapping 
let url = URL(fileURLWithPath: path) 

path.withCString { s1 in 
    url.withUnsafeFileSystemRepresentation { s2 in 
     print(strcmp(s1, s2) == 0) // false 
    } 
} 

財団APIを使用して(FileManagerURL、...)が推奨されている場合、 です。ファイルシステムの表現には注意する必要はありません。

関連する問題