我在iOS应用程序上使用以下Swift代码从服务器下载文本文件:
func stream(theStream : NSStream, handleEvent streamEvent : NSStreamEvent)
{
println("stream event \(streamEvent)")
switch (streamEvent)
{
case NSStreamEvent.None:
println("NSStreamEventNone")
case NSStreamEvent.OpenCompleted:
println("NSStreamEventOpenCompleted")
case NSStreamEvent.HasBytesAvailable:
println("NSStreamEvent.HasBytesAvailable")
if let inputStream = theStream as? NSInputStream
{
//println("is NSInputStream")
if inputStream.hasBytesAvailable
{
//println("hasBytesAvailable")
let bufferSize = 4096
var buffer = Array<UInt8>(count: bufferSize, repeatedValue: 0)
var bytesRead: Int = inputStream.read(&buffer, maxLength: bufferSize)
// If read bytes are less than 0 -> error
if bytesRead < 0
{
self.error = self.inputStream!.streamError
closeNetworkCommunication()
}
// If read bytes equal 0 -> close connection
else if bytesRead == 0
{
closeNetworkCommunication()
}
// If read bytes are greater than 0
else if bytesRead > 0
{
var messageFromServer: NSString = NSString(bytes: &buffer, length: bytesRead, encoding: NSUTF8StringEncoding)!
//println(output)
messageReceived(messageFromServer)
closeNetworkCommunication()
}
}
}
case NSStreamEvent.HasSpaceAvailable:
println("NSStreamEventHasSpaceAvailable")
case NSStreamEvent.ErrorOccurred:
println("NSStreamEventErrorOccurred")
case NSStreamEvent.EndEncountered:
println("NSStreamEventEndEncountered")
default:
println("Unknown event")
}
}
文件下载得很好,但它仅限于缓冲区大小(4096),因此经常被截断。有很多文件可以下载,大小从1 kb到300 kb甚至更多。因此,我可以使缓冲区大小等于4096000,它将下载整个文件。但有没有更好的方法来设置无限(即动态)缓冲区?
编辑:
我将代码修改为以下内容:
case NSStreamEvent.HasBytesAvailable:
var buffer = [UInt8](count: 4096, repeatedValue: 0)
if ( theStream == self.inputStream)
{
while (self.inputStream!.hasBytesAvailable)
{
var len = inputStream!.read(&buffer, maxLength: buffer.count)
// If read bytes are less than 0 -> error
if len < 0
{
self.error = self.inputStream!.streamError
println("Input stream has less than 0 bytes")
closeNetworkCommunication()
}
// If read bytes equal 0 -> close connection
else if len == 0
{
println("Input stream has 0 bytes")
closeNetworkCommunication()
}
if(len > 0)
{
var messageFromServer = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding)
messageReceived(messageFromServer!)
}
}
}
现在可以使用并下载完整的文件。我现在的问题是我是否需要在下载文件后关闭TCP连接以及如何。
我使用以下内容来关闭沟通:
func closeNetworkCommunication()
{
self.inputStream?.close()
self.outputStream?.close()
self.inputStream?.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
self.outputStream?.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
self.inputStream?.delegate = nil
self.outputStream?.delegate = nil
self.inputStream = nil;
self.outputStream = nil;
//self.inputBuffer = nil;
self.outputBuffer = nil;
println("LOAD CLOSENETWORKCOMMUNICATION")
}
因此,如果我在HasBytesAvailable子句中关闭网络,它会停止加载消息并崩溃(在解开Optional值时意外发现nil)。即使我最后在我的messageReceived(messageFromServer!)方法中关闭网络,也会发生同样的事情。如何在不截断文件的情况下关闭网络?
非常感谢!