this question的解决方案不再适用于Swift 3.
不再有bytes
Data
的属性{以前为NSData
。
let data = dataToWrite.first!
self.outputStream.write(&data, maxLength: data.count)
使用此代码,我收到错误:
Cannot convert value of type 'Data' to expected argument type 'UInt8'
如何在Swift 3中将Data
写入NSOutputStream
?
答案 0 :(得分:12)
NSData
有bytes
属性来访问字节。
Swift 3中新的Data
值类型有withUnsafeBytes()
相反,它使用指向字节的指针调用闭包。
这就是你将Data
写入NSOutputStream
的方式
(不转换为NSData
):
let data = ... // a Data value
let bytesWritten = data.withUnsafeBytes { outputStream.write($0, maxLength: data.count) }
说明:
withUnsafeBytes()
是一种通用方法:
/// Access the bytes in the data.
///
/// - warning: The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.
public func withUnsafeBytes<ResultType, ContentType>(_ body: @noescape (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType
在上面的电话中,
自动推断ContentType
和ResultType
编译器(作为UInt8
和Int
),另外做了
UnsafePointer()
转换不必要。
outputStream.write()
返回实际写入的字节数。
通常,您应该检查该值。它可以是-1
if
写入操作失败,或写入时小于data.count
插座,管道或其他带流量控制的物体。
答案 1 :(得分:4)
Martin R ,谢谢你的回答。这是完整解决方案的基础。这是:
extension OutputStream {
/// Write String to outputStream
///
/// - parameter string: The string to write.
/// - parameter encoding: The String.Encoding to use when writing the string. This will default to UTF8.
/// - parameter allowLossyConversion: Whether to permit lossy conversion when writing the string.
///
/// - returns: Return total number of bytes written upon success. Return -1 upon failure.
func write(_ string: String, encoding: String.Encoding = String.Encoding.utf8, allowLossyConversion: Bool = true) -> Int {
if let data = string.data(using: encoding, allowLossyConversion: allowLossyConversion) {
var bytesRemaining = data.count
var totalBytesWritten = 0
while bytesRemaining > 0 {
let bytesWritten = data.withUnsafeBytes {
self.write(
$0.advanced(by: totalBytesWritten),
maxLength: bytesRemaining
)
}
if bytesWritten < 0 {
// "Can not OutputStream.write(): \(self.streamError?.localizedDescription)"
return -1
} else if bytesWritten == 0 {
// "OutputStream.write() returned 0"
return totalBytesWritten
}
bytesRemaining -= bytesWritten
totalBytesWritten += bytesWritten
}
return totalBytesWritten
}
return -1
}
}
答案 2 :(得分:3)
只需使用此扩展程序(Swift 4)
extension OutputStream {
func write(data: Data) -> Int {
return data.withUnsafeBytes { write($0, maxLength: data.count) }
}
}
对于InputStream
extension InputStream {
func read(data: inout Data) -> Int {
return data.withUnsafeMutableBytes { read($0, maxLength: data.count) }
}
}
答案 3 :(得分:0)
Data
和NSData
是Swift 3中的两个单独的类,Data
没有bytes
属性。
解决方案是将data
定义为类型NSData
let data: NSData = dataToWrite.first!
self.outputStream.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
根据 Migrating to Swift 2.3 or Swift 3 from Swift 2.2 :
迁移器会将NSData的大部分用途转换为新的值类型Data。但是,NSData上的某些方法对UnsafeMutablePointer进行操作,而Data上的相应方法使用UnsafeMutablePointer。 (例如,NSData.getBytes(:length :)比Data.copyBytes(:length :)更容易接受。)作为提醒,不保证Swift类型的内存中布局。