【问题标题】:Read large file of binary data in chunks of 1024 bytes以 1024 字节的块读取大的二进制数据文件
【发布时间】:2020-04-24 19:29:17
【问题描述】:

我正在尝试以 1024 字节的块读取 MP4 文件。我编写了一个几乎可以工作的代码。我正在执行以下操作:

let audioFilePath = Bundle.main.path(forResource: "video", ofType: "mp4")!
var chunks = [[UInt8]]()

  if let stream: InputStream = InputStream(fileAtPath: audioFilePath) {
    var buf: [UInt8] = [UInt8](repeating: 0, count: 1024)
    stream.open()
    while stream.hasBytesAvailable {
      stream.read(&buf, maxLength: 1024)
      chunks.append(buf)
    }
    stream.close()
  }

print(chunks.count)

上面代码的问题是我正在读取大小为 15.948.514 字节的 MP4 文件。这意味着它应该恰好在 15.574 个块中完成(最后一个块可能少于 1024,但这不是问题),但是代码打印了 15.576 个块,并且它们的大小都是 1024。上面的代码有什么问题?

【问题讨论】:

    标签: swift file-io binaryfiles


    【解决方案1】:

    如果必须尝试读取以确定字节的可用性,hasBytesAvailable 也可以返回 true。这就是在您的情况下发生的情况:对于“文件结尾”,最终读取返回零。

    hasBytesAvailable 可用于 TCP 套接字之类的输入流,以避免阻塞 read(),但实际上并不需要从文件中读取。在任何情况下,您都必须检查read() 的返回值,该值可以是零(文件结尾)或-1(读取错误)或读入缓冲区的实际字节数(可以小于请求的字节数)。

    还请注意,您始终将一个 1024 字节的块附加到 chunks 数组,即使缓冲区仅部分填充了来自输入流的字节。

    if let stream = InputStream(fileAtPath: audioFilePath) {
        var buf = [UInt8](repeating: 0, count: 1024)
        stream.open()
    
        while case let amount = stream.read(&buf, maxLength: 1024), amount > 0 {
            // print(amount)
            chunks.append(Array(buf[..<amount]))
        }
        stream.close()
    }
    

    【讨论】:

      猜你喜欢
      • 2013-12-06
      • 2023-02-26
      • 2020-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      相关资源
      最近更新 更多