Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// Marcin Krzyzanowski
// blog.krzyzanowskim.com
import Foundation
extension URLResourceKey {
static let bookmarkAllPropertiesKey = URLResourceKey("NSURLBookmarkAllPropertiesKey")
static let fileIDKey = URLResourceKey("_NSURLFileIDKey")
static let inode = URLResourceKey.fileIDKey
}
private func getInode(for fileURL: URL) throws -> Int {
// ls -i /tmp/file.txt
var tmp = fileURL
tmp.removeCachedResourceValue(forKey: .inode)
return try fileURL.resourceValues(forKeys: [.inode]).allValues[.inode] as! Int
}
private func checkAtomicWrite(for fileURL: URL) throws -> (Int, Int) {
let inodeBefore = try getInode(for: fileURL)
try "foobar".write(to: fileURL, atomically: true, encoding: .utf8)
let inodeAfter = try getInode(for: fileURL)
return (inodeBefore, inodeAfter)
}
private func checkNonAtomicWrite(for fileURL: URL) throws -> (Int, Int) {
let inodeBefore = try getInode(for: fileURL)
try "foobar".write(to: fileURL, atomically: false, encoding: .utf8)
let inodeAfter = try getInode(for: fileURL)
return (inodeBefore, inodeAfter)
}
// Check inode values
let fileURL = URL(fileURLWithPath: "/tmp/file.txt")
// Create empty file
if FileManager.default.fileExists(atPath: fileURL.path) {
FileManager.default.removeItem(at: fileURL)
}
FileManager.default.createFile(atPath: fileURL.path, contents: nil, attributes: nil)
// Test inode changes
let (inodeBeforeAtomic, inodeAfterAtomic) = try checkAtomicWrite(for: fileURL)
if (inodeBeforeAtomic != inodeAfterAtomic) {
print("[Atomic] inode value changed: \(inodeBeforeAtomic) -> \(inodeAfterAtomic)")
}
let (inodeBeforeNonAtomic, inodeAfterNonAtomic) = try checkNonAtomicWrite(for: fileURL)
if (inodeBeforeNonAtomic != inodeAfterNonAtomic) {
print("[Non atomic] inode value changed: \(inodeBeforeNonAtomic) -> \(inodeAfterNonAtomic)")
}
// Check bookmarks
do {
// Create bookmark
let bookmark = try fileURL.bookmarkData()
// Modify file
try "foobar".write(to: fileURL, atomically: true, encoding: .utf8)
// Move file to /tmp/file.txt.bak
try FileManager.default.moveItem(at: fileURL, to: fileURL.appendingPathExtension("bak"))
// Try to use bookmark 💥 Error: The file doesn’t exist.
var bookmarkIsStale = false
try URL(resolvingBookmarkData: bookmark, bookmarkDataIsStale: &bookmarkIsStale)
} catch {
print(error)
}
// Cleanup
FileManager.default.removeItem(at: fileURL.appendingPathExtension("bak"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.