Skip to content

Instantly share code, notes, and snippets.

@KeyYao
Created November 1, 2019 10:26
Show Gist options
  • Save KeyYao/43bc7ce626c2b8884f174a4f73ae0fa4 to your computer and use it in GitHub Desktop.
Save KeyYao/43bc7ce626c2b8884f174a4f73ae0fa4 to your computer and use it in GitHub Desktop.
//
// FileHandleInputStream.swift
// FileHandleInputStream
//
// 参考: https://gist.github.com/khanlou/b5e07f963bedcb6e0fcc5387b46991c3
//
// Created by Key.Yao on 2019/11/1.
// Copyright © 2019 Key.Yao. All rights reserved.
//
import Foundation
class FileHandleInputStream: InputStream {
private let mFileHandle: FileHandle
private var _streamStatus: Stream.Status
private var _streamError: Error?
private var _delegate: StreamDelegate?
init(fileHandle: FileHandle, offset: UInt64) {
self.mFileHandle = fileHandle
self.mFileHandle.seek(toFileOffset: offset)
self._streamStatus = .notOpen
self._streamError = nil
super.init(data: Data())
}
override var streamStatus: Stream.Status {
return _streamStatus
}
override var streamError: Error? {
return _streamError
}
override var delegate: StreamDelegate? {
get {
return _delegate
}
set {
_delegate = newValue
}
}
override func read(_ buffer: UnsafeMutablePointer<UInt8>, maxLength len: Int) -> Int {
if _streamStatus == .closed {
return 0
}
var totalBytesRead = 0
while totalBytesRead < len {
let requiredLength = len - totalBytesRead
let data = self.mFileHandle.readData(ofLength: requiredLength)
let readLength = data.count
if readLength == 0 {
if requiredLength == len {
self.close()
return 0
} else {
break
}
}
data.copyBytes(to: buffer, count: readLength)
totalBytesRead += readLength
}
return totalBytesRead
}
override func getBuffer(_ buffer: UnsafeMutablePointer<UnsafeMutablePointer<UInt8>?>, length len: UnsafeMutablePointer<Int>) -> Bool {
return false
}
override var hasBytesAvailable: Bool {
return true
}
override func open() {
guard self._streamStatus == .open else {
return
}
self._streamStatus = .open
}
override func close() {
self._streamStatus = .closed
}
override func property(forKey key: Stream.PropertyKey) -> Any? {
return nil
}
override func setProperty(_ property: Any?, forKey key: Stream.PropertyKey) -> Bool {
return false
}
override func schedule(in aRunLoop: RunLoop, forMode mode: RunLoop.Mode) {
}
override func remove(from aRunLoop: RunLoop, forMode mode: RunLoop.Mode) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment