作为我项目的一部分,我有一个二进制数据文件,由一系列32位整数组成,我的一个类在初始化时读入。在我的C ++库中,我使用以下初始化程序读取它:
Evaluator::Evaluator() {
m_HandNumbers.resize(32487834);
ifstream inputReader;
inputReader.open("/path/to/file/7CHands.dat", ios::binary);
int inputValue;
for (int x = 0; x < 32487834; ++x) {
inputReader.read((char *) &inputValue, sizeof (inputValue));
m_HandNumbers[x] = inputValue;
}
inputReader.close();
};
在移植到Swift时,我决定将整个文件读入一个缓冲区(它只有大约130 MB),然后将这些字节从缓冲区中复制出来。
所以,我做了以下事情:
public init() {
var inputStream = NSInputStream(fileAtPath: "/path/to/file/7CHands.dat")!
var inputBuffer = [UInt8](count: 32478734 * 4, repeatedValue: 0)
inputStream.open()
inputStream.read(&inputBuffer, maxLength: inputBuffer.count)
inputStream.close()
}
它运行正常,当我调试它时,我可以看到inputBuffer包含我的十六进制编辑器应该说的相同的字节数组。现在,我想有效地从那里获取数据。我知道它存储在......你称之为最低有效字节为止的任何格式(即数字0x00011D4A在文件中表示为'4A1D 0100')。我很想手动迭代它并手动计算字节值,但我想知道是否有一种快速方法可以传递[Int32]数组并让它读取这些字节。我尝试使用NSData,例如:
let data = NSData(bytes: handNumbers, length: handNumbers.count * sizeof(Int32))
data.getBytes(&inputBuffer, length: inputBuffer.count)
但似乎没有加载值(所有值仍为零)。有人可以帮我把这个字节数组转换成一些Int32值吗?更好的是将它们转换为Int(即64位整数),以保持我的变量大小在整个项目中保持不变。
答案 0 :(得分:3)
不确定您的字符串,但我使用以下功能。与代码的不同之处在于使用实际所需类型的NSRanges
,而不是字节长度。该例程一次读取一个值(对于ESRI文件,其内容逐字段变化),但应该很容易适应。
func getBigIntFromData(data: NSData, offset: Int) -> Int {
var rng = NSRange(location: offset, length: 4)
var i = [UInt32](count: 1, repeatedValue:0)
data.getBytes(&i, range: rng)
return Int(i[0].bigEndian)// return Int(i[0]) for littleEndian
}
答案 1 :(得分:2)
Grimxn为我的问题提供了解决方案的主干,它向我展示了如何将缓冲区的部分读入数组;然后他告诉我一种方法可以同时读取整个缓冲区。我不必将数组中的所有项目不必要地转换为Int
,而只是将数组作为UInt32读入缓冲区,并在访问该数组的函数中进行转换为Int
。
目前,由于我还没有定义我的实用程序类,我将Grimxn的代码直接集成到我的初始化程序中。类初始化程序现在看起来像这样:
public class Evaluator {
let HandNumberArraySize = 32487834
var handNumbers: [Int32]
public init() {
let data = NSData(contentsOfFile: "/path/to/file/7CHands.dat")!
var dataRange = NSRange(location: 0, length: HandNumberArraySize * 4)
handNumbers = [Int32](count: HandNumberArraySize, repeatedValue: 0)
data.getBytes(&handNumbers, range: dataRange)
println("Evaluator loaded successfully")
}
...
}
...现在引用它们的函数是:
public func cardVectorToHandNumber(#cards: [Int], numberToUse: Int) -> Int {
var output: Int
output = Int(handNumbers[53 + cards[0] + 1])
for i in 1 ..< numberToUse {
output = Int(handNumbers[output + cards[i] + 1])
}
return Int(handNumbers[output])
}
感谢Grimxn,再次感谢StackOverflow以非常真实的方式帮助我!