问题描述
我正在为日志文件生成一个本地文件并将其上传到服务器。但它因致命异常:NSFileHandleOperationException -[NSConcreteFileHandle writeData:]: Invalid argument 而崩溃。下面是我的 LogFileManager 类。崩溃指向 saveLog 函数,下面是堆栈跟踪
Fatal Exception: NSFileHandleOperationException
0 CoreFoundation 0x182879344 __exceptionPreprocess
1 libobjc.A.dylib 0x18258ecc0 objc_exception_throw
2 Foundation 0x182c1c050 -[NSConcreteFileHandle readDataUpToLength:error:]
3 Foundation 0x182ba7504 -[NSConcreteFileHandle writeData:]
4 MyMobileApp 0x10122dfb4 closure #1 in static LogFileManager.saveLog(logParameters:) (<compiler-generated>)
5 MyMobileApp 0x1013b64e0 thunk for @callee_guaranteed () -> () (<compiler-generated>)
6 MyMobileApp 0x1013b6500 thunk for @escaping @callee_guaranteed () -> () (<compiler-generated>)
7 libdispatch.dylib 0x18251b5ac _dispatch_client_callout
8 libdispatch.dylib 0x18251fa34 _dispatch_sync_function_invoke
9 MyMobileApp 0x10122db18 static LogFileManager.saveLog(logParameters:) (<compiler-generated>)
10 MyMobileApp 0x101385cd8 static LogManagerAPI.updateLog(_:url:responseStatus:response:httpMethod:parameters:httpHeaderField:) + 57 (LogManagerAPI.swift:57)
11 MyMobileApp 0x1015fe294 ServiceResponse.logResponse() + 16 (LogManager.swift:16)
12 MyMobileApp 0x1011f54e4 closure #1 in ServiceRESTAPI.callService<A>(completion:) + 189 (ServiceRequestProtocol.swift:189)
13 Alamofire 0x106a6f4e0 (Missing)
14 Alamofire 0x106a733c4 (Missing)
15 Alamofire 0x106a4d6d8 (Missing)
16 libdispatch.dylib 0x18251a134 _dispatch_call_block_and_release
17 libdispatch.dylib 0x18251b5ac _dispatch_client_callout
18 libdispatch.dylib 0x1825277d4 _dispatch_main_queue_callback_4CF
19 CoreFoundation 0x1827f48d4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_disPATCH_QUEUE__
20 CoreFoundation 0x1827ef58c __CFRunLoopRun
21 CoreFoundation 0x1827eebc8 CFRunLoopRunSpecific
22 GraphicsServices 0x18cbd75cc GSEventRunModal
23 UIKitCore 0x1869a1744 UIApplicationMain
24 MyMobileApp 0x10100ddb0 main + 33 (AppDelegate.swift:33)
25 libdyld.dylib 0x18266b384 start
这是我的 LogFileManager 类
class LogFileManager {
static var logFile: URL? {
guard let documentDirectoryURL = try? FileManager.default.url(for: .documentDirectory,in: .userDomainMask,appropriateFor: nil,create: false) else {
return nil
}
return documentDirectoryURL.appendingPathComponent(Constants.FileName.elkLogFile)
}
static func handleFileSize(filePath: String) {
let file: FileHandle? = FileHandle(forReadingAtPath: filePath)
file?.seek(toFileOffset: 500000)
let databuffer = file?.readDataToEndOfFile()
let tempuRL = createLogDataFile(withData: databuffer,withFileName: "LogFile.txt")
replaceExistingFile(withTempFile: tempuRL)
file?.closeFile()
}
static func sizePerMB(url: URL?) -> Double {
guard let filePath = url?.path else {
return 0.0
}
do {
let attribute = try FileManager.default.attributesOfItem(atPath: filePath)
if let size = attribute[FileAttributeKey.size] as? NSNumber {
return size.doubleValue / (1024 * 1024)
}
} catch {
print("Error getting size")
}
return 0.0
}
static func createLogDataFile(withData data: Data?,withFileName name: String) -> URL? {
if let destinationURL = FileManager.default.urls(for: .documentDirectory,in: .userDomainMask).first {
let fileManager = FileManager.default
var itemReplacementDirectoryURL: URL?
do {
try itemReplacementDirectoryURL = fileManager.url(for: .itemReplacementDirectory,appropriateFor: destinationURL,create: true)
} catch _ {
print("Failed to replace file")
}
guard let destURL = itemReplacementDirectoryURL else {return nil}
guard let data = data else {return nil}
let tempFileURL = destURL.appendingPathComponent(name)
do {
try data.write(to: tempFileURL,options: .atomic)
removeLogFile()
return tempFileURL
} catch _ {
print("Failed to write file")
return nil
}
}
return nil
}
static func replaceExistingFile(withTempFile fileURL: URL?) {
guard let fileURL = fileURL else {return}
if let destPath = logFile {
do {
let dta = try Data(contentsOf: fileURL)
try dta.write(to: destPath,options: .atomic)
}
catch _ {
print("Failed to replace the logfile with tempfile")
}
}
}
static func removeLogFile() {
let filemanager = FileManager.default
if let logFile = logFile {
do {
try filemanager.removeItem(atPath: logFile.path)
} catch _ as NSError {
print("Failed to delete the log file")
}
}
}
static func saveLog(logParameters: [String: String]) {
guard let logFile = logFile else {
return
}
let log: LogModel = LogModel(logParameters)
let encoder = JSONEncoder()
guard var jsonData = try? encoder.encode(log) else {
return
}
guard let commaAddition = ",".data(using: String.Encoding.utf8) else {
return
}
jsonData.append(commaAddition)
dispatchQueue.global(qos: .background).sync {
if FileManager.default.fileExists(atPath: logFile.path) {
if sizePerMB(url: logFile) >= 5 {
handleFileSize(filePath: logFile.path)
}
let fileHandle = try? FileHandle(forWritingTo: logFile)
fileHandle?.seekToEndOfFile()
fileHandle?.write(jsonData)
fileHandle?.closeFile()
} else {
try? jsonData.write(to: logFile,options: .atomicWrite)
}
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)