以 1024 字节的块读取二进制数据的大文件

Read large file of binary data in chunks of 1024 bytes

我正在尝试以 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。上面的代码有什么问题?

如果必须尝试读取以确定字节的可用性,

hasBytesAvailable 也可以 return true。这就是您的情况:最终读取 return“文件结尾”为零。

hasBytesAvailable 可用于 TCP 套接字之类的输入流,以避免阻塞 read(),但实际上并不需要从文件中读取。在任何情况下,您都必须检查 read() 的 return 值,它可以是零(文件结尾)或 -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()
}