Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch NSFileHandleOperationException in Swift

How can I catch a NSFileHandleOperationException in Swift?

I use fileHandle.readDataToEndOfFile() which calls (according to the documentation) fileHandle.readDataOfLength() which can throw (again according to the documentation) a NSFileHandleOperationException.

How can I catch this exception? I tried

do {
    return try fH.readDataToEndOfFile()
} catch NSFileHandleOperationException {
    return nil
}

but Xcode says

Warning: No calls to throwing functions occur within 'try' expression

Warning: 'catch' block is unreachable because no errors are thrown in 'do' block

How do I do this? 😄

Edit: I just decided to use C's good old fopen, fread, fclose as a workaround:

extension NSMutableData {
    public enum KCStd$createFromFile$err: ErrorType {
        case Opening, Reading, Length
    }
    
    public static func KCStd$createFromFile(path: String, offset: Int = 0, length: Int = 0) throws -> NSMutableData {
        let fh = fopen(NSString(string: path).UTF8String, NSString(string: "r").UTF8String)
        if fh == nil { throw KCStd$createFromFile$err.Opening }
        defer { fclose(fh) }
    
        fseek(fh, 0, SEEK_END)
        let size = ftell(fh)
        fseek(fh, offset, SEEK_SET)
    
        let toRead: Int
        if length <= 0 {
            toRead = size - offset
        } else if offset + length > size {
            throw KCStd$createFromFile$err.Length
        } else {
            toRead = length
        }
    
        let buffer = UnsafeMutablePointer<UInt8>.alloc(toRead)
        defer {
            memset_s(buffer, toRead, 0x00, toRead)
            buffer.destroy(toRead)
            buffer.dealloc(toRead)
        }
        let read = fread(buffer, 1, toRead, fh)
        if read == toRead {
            return NSMutableData(bytes: buffer, length: toRead)
        } else {
            throw KCStd$createFromFile$err.Reading
        }
    }
}

KCStd$ (abbreviation for KizzyCode Standard Library) is the prefix because extensions are module-wide. The above code is hereby placed in Public Domain 😊

I'll leave this open because it's nonetheless an interesting question.

like image 870
K. Biermann Avatar asked Aug 20 '15 17:08

K. Biermann


1 Answers

The answer seems to be that you can't. If you look at the declarations in FileHandle, you will see comment:

/* The API below may throw exceptions and will be deprecated in a future version of the OS.
 Use their replacements instead. */
like image 86
escrafford Avatar answered Nov 13 '22 22:11

escrafford