在Swift中,如何将现有的二进制文件读入数组? [英] In Swift, how do I read an existing binary file into an array?

查看:416
本文介绍了在Swift中,如何将现有的二进制文件读入数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为我的项目的一部分,我有一个二进制数据文件,该文件由一系列32位整数组成,我的一个类在初始化时就读取了这些数据.在我的C ++库中,我使用以下初始化程序将其读入:

As part of my projects, I have a binary data file consisting of a large series of 32 bit integers that one of my classes reads in on initialization. In my C++ library, I read it in with the following initializer:

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),然后将字节复制到缓冲区之外.

and in porting to Swift, I decided to read the entire file into one buffer (it's only about 130 MB) and then copy the bytes out of the buffer.

因此,我已完成以下操作:

So, I've done the following:

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,例如:

and it works fine in that when I debug it, I can see inputBuffer contains the same array of bytes that my hex editor says it should. Now, I'd like to get that data out of there effectively. I know it's stored in.. whatever format you call it where the least significant bytes are first (i.e. the number 0x00011D4A is represented as '4A1D 0100' in the file). I'm tempted to just iterate through it manually and calculate the byte values by hand, but I'm wondering if there's a quick way I can pass an array of [Int32] and have it read those bytes in. I tried using NSData, such as with:

    let data = NSData(bytes: handNumbers, length: handNumbers.count * sizeof(Int32))
    data.getBytes(&inputBuffer, length: inputBuffer.count)

但这似乎没有加载值(所有值仍为零).谁能帮我把这个字节数组转换成一些Int32值吗?更好的办法是将它们转换为Int(即64位整数),只是为了使我的变量大小在整个项目中保持不变.

but that didn't seem to load the values (all the values were still zero). Can anyone please help me convert this byte array into some Int32 values? Better yet would be to convert them to Int (i.e. 64 bit integer) just to keep my variable sizes the same across the project.

推荐答案

不确定您的字节序,但是我使用以下功能.与您的代码的区别是使用实际所需类型的NSRanges,而不是字节的长度.此例程一次读取一个值(适用于ESRI文件,其内容随字段而异),但应易于适应.

Not sure about your endian-ness, but I use the following function. The difference from your code is using NSRanges of the actual required type, rather than lengths of bytes. This routine reads one value at a time (it's for ESRI files whose contents vary field by field), but should be easily adaptable.

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
}

这篇关于在Swift中,如何将现有的二进制文件读入数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆