以 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()
}
我正在尝试以 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()
}