swift - 在 swift 1.2 中逐行读取文件

标签 swift

<分区>

在以前的 swift 版本中,我可以使用这篇文章的答案: Read a file/URL line-by-line in Swift

快速逐行读取文件。现在我已经升级到 1.2,这似乎不再编译。在 swift 1.2 中是否有更新的逐行读取文件的方法?

最佳答案

这是 Swift 1.2 的 StreamReader 的更新版本(如果有人想检查它以确保它没问题,现在 1.2 是当前发布的版本,可能应该编辑到原始答案中版本):

class StreamReader  {

    let encoding : UInt
    let chunkSize : Int

    var fileHandle : NSFileHandle!
    let buffer : NSMutableData!
    let delimData : NSData!
    var atEof : Bool = false

    init?(path: String, delimiter: String = "\n", encoding : UInt = NSUTF8StringEncoding, chunkSize : Int = 4096) {
        self.chunkSize = chunkSize
        self.encoding = encoding

        if let fileHandle = NSFileHandle(forReadingAtPath: path),
               delimData = delimiter.dataUsingEncoding(NSUTF8StringEncoding),
               buffer = NSMutableData(capacity: chunkSize)
        {
            self.fileHandle = fileHandle
            self.delimData = delimData
            self.buffer = buffer
        } else {
            self.fileHandle = nil
            self.delimData = nil
            self.buffer = nil
            return nil
        }
    }

    deinit {
        self.close()
    }

    /// Return next line, or nil on EOF.
    func nextLine() -> String? {
        precondition(fileHandle != nil, "Attempt to read from closed file")

        if atEof {
            return nil
        }

        // Read data chunks from file until a line delimiter is found:
        var range = buffer.rangeOfData(delimData, options: nil, range: NSMakeRange(0, buffer.length))
        while range.location == NSNotFound {
            var tmpData = fileHandle.readDataOfLength(chunkSize)
            if tmpData.length == 0 {
                // EOF or read error.
                atEof = true
                if buffer.length > 0 {
                    // Buffer contains last line in file (not terminated by delimiter).
                    let line = NSString(data: buffer, encoding: encoding)

                    buffer.length = 0
                    return line as String?
                }
                // No more lines.
                return nil
            }
            buffer.appendData(tmpData)
            range = buffer.rangeOfData(delimData, options: nil, range: NSMakeRange(0, buffer.length))
        }

        // Convert complete line (excluding the delimiter) to a string:
        let line = NSString(data: buffer.subdataWithRange(NSMakeRange(0, range.location)),
            encoding: encoding)
        // Remove line (and the delimiter) from the buffer:
        buffer.replaceBytesInRange(NSMakeRange(0, range.location + range.length), withBytes: nil, length: 0)

        return line as String?
    }

    /// Start reading from the beginning of file.
    func rewind() -> Void {
        fileHandle.seekToFileOffset(0)
        buffer.length = 0
        atEof = false
    }

    /// Close the underlying file. No reading must be done after calling this method.
    func close() -> Void {
        fileHandle?.closeFile()
        fileHandle = nil
    }
}

关于swift - 在 swift 1.2 中逐行读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29540593/

相关文章:

ios - Objective-C:如何让AVPlayer在后台继续播放

xcode - 如何在 ScrollView 中使用自动布局?

ios - 在代码中配置 NSAppTransportSecurity

Swift 延迟问题

ios - 为什么页面控件不反射(reflect)我在 UIScrollView 上的位置?

ios - 在 iOS Swift 中,在 Swift 4 中的 TableView 内集成 CollectionView 的不同数组

ios - 无法使用 '[item]' 类型的索引为 'item' 类型的值添加下标

ios - 如何使用 XCode 在 iOS 中的媒体播放器应用程序中制作一个正在播放的栏?

swift - 如何在 ""内打印双引号?

ios - 在不为后退滑动按钮设置动画的情况下呈现警报