Swift:NSStreamEvent.HasBytesAvailable - 动态缓冲区

时间:2015-09-02 03:08:44

标签: swift buffer tcpclient nsstream

我在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!)方法中关闭网络,也会发生同样的事情。如何在不截断文件的情况下关闭网络?

非常感谢!

0 个答案:

没有答案