如何在Swift的InputStream中自定义实现skip()跳过指定字节的方法
Swift 实现InputStream skip方法的方案
Swift 的 Foundation 框架中InputStream未提供原生的skip方法,你可以通过读取并丢弃指定长度字节的方式实现兼容全类型输入流的skip功能,实现代码如下:
/** * Skips n bytes of input. * @param n the number of bytes to skip * @return the actual number of bytes skipped. */ func skip(n: Int) throws -> Int { guard n > 0 else { return 0 } // 单次读取缓冲区大小,可根据场景调整,1KB为通用合理值 let bufferSize = 1024 let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize) defer { buffer.deallocate() } var totalSkipped = 0 while totalSkipped < n { let remainingToSkip = n - totalSkipped let readLength = min(bufferSize, remainingToSkip) let bytesRead = inputStream.read(buffer, maxLength: readLength) // 处理读取错误 if bytesRead < 0 { throw inputStream.streamError ?? NSError( domain: NSPOSIXErrorDomain, code: Int(EIO), userInfo: [NSLocalizedDescriptionKey: "Input stream read failed"] ) } // 读到流末尾,终止循环 if bytesRead == 0 { break } totalSkipped += bytesRead } pos_ += totalSkipped return totalSkipped }
如果你的InputStream是通过文件路径初始化的文件流,可使用seek方法实现更高性能的跳过,避免冗余IO操作:
// 仅适用于文件类型InputStream的高性能skip实现 func fileStreamSkip(n: Int) throws -> Int { guard let fileStream = inputStream as? FileInputStream else { throw NSError( domain: "InputStreamError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Current stream is not a file input stream"] ) } let originOffset = fileStream.offsetInFile try fileStream.seek(toOffset: originOffset + n) let actualSkipped = fileStream.offsetInFile - originOffset pos_ += actualSkipped return Int(actualSkipped) }
注意事项:
- 调用skip方法前需要确保
InputStream已经执行open()操作,处于可读取状态 - 网络流场景下如果触发读取超时,会通过
streamError抛出对应异常
内容的提问来源于stack exchange,提问作者Max Mur
相关产品推荐
相关产品推荐

