【问题标题】:Opening a strait binary file with iOS用 iOS 打开一个海峡二进制文件
【发布时间】:2013-06-12 01:37:46
【问题描述】:

我编写了一个自定义文件类型,用于保存来自我的 Java 程序的数据。我想在 iPod/Pad/Phone 上获取数据。到目前为止,我编写了这个文件,用于从文件中读取海峡字节值并将它们更改为 NSStrings 和整数。

#import "BinaryFileReader.h"

@implementation BinaryFileReader

- (id)init {
    self = [super init];
    return self;
}

- (id)initWithLocation:(NSString*)filepath {
    if ((self = [super init])) {
        _file = [NSFileHandle fileHandleForReadingAtPath:filepath];
        _fileOffset = 0;
        if (_file == nil)
            NSLog(@"%@%@",@"Failed to open file at path:",filepath);
    }
    return self;
}

- (void)close {
    [_file closeFile];
}

- (int)readInt {
    [_file seekToFileOffset:_fileOffset];
    _databuffer = [_file readDataOfLength:4];
    _fileOffset+=4;
    return (int)[_databuffer bytes];
}

- (NSString*)readNSString {
    int length = [self readInt];
    [_file seekToFileOffset:_fileOffset];
    _databuffer = [_file readDataOfLength:length];
    _fileOffset+=length;
    return [[NSString alloc] initWithData:_databuffer encoding:NSUTF8StringEncoding];
}

- (NSMutableArray*)readNSMutableArrayOfNSString {
    NSMutableArray* array = [[NSMutableArray alloc] init];
    int arrayLength = [self readInt];
    int length;
    for (int i=0; i<arrayLength; i++) {
        length = [self readInt];
        [_file seekToFileOffset:_fileOffset];
        _databuffer = [_file readDataOfLength:length];
        _fileOffset+=length;
        [array addObject:[[NSString alloc] initWithData:_databuffer encoding:NSUTF8StringEncoding]];
    }
    return array;
}

@end

现在,当我尝试使用它来读取 NSStrings 或整数时,它没有得出正确的值。我假设由于 NSStrings 和整数都出现错误,这是 readInt 方法中的问题。有人看到我在这里错过的明显的东西吗?

编辑:

我尝试读取的文件格式以字符串开头。该字符串在使用 readNSString 读取时是正确的字符串,但缺少该字符串的前 1/3。

Java 代码:

public void saveItem() {
    try {
        byte[] bytes;
        FileOutputStream output;
        if (countOccurrences(location.getPath(),'.')==1) {
            System.out.println("Option 1");
            output = new FileOutputStream(location+"/"+name+".dtb");
        } else {
            output = new FileOutputStream(location);
        }

        bytes = name.getBytes("UTF-8");
        output.write(bytes.length);
        output.write(bytes);

        output.write(otherNames.length);
        for (int i=0;i<otherNames.length;i++) {
            bytes = otherNames[i].getBytes("UTF-8");
            output.write(bytes.length);
            output.write(bytes);
        }

        bytes = description.getBytes("UTF-8");
        output.write(bytes.length);
        output.write(bytes);

        bytes = XactCode.getBytes("UTF-8");
        output.write(bytes.length);
        output.write(bytes);

        bytes = SymbilityCode.getBytes("UTF-8");
        output.write(bytes.length);
        output.write(bytes);

        output.write(averageLowPrice);

        output.write(averageHighPrice);

        output.write(averageLifeExpectancy);

        output.close();
        bytes = null;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

【问题讨论】:

  • Endian 问题浮现在脑海。如果您的 Java 程序在 Windows 上运行,那么所有字节都将与您想要的相反。
  • 好吧,我可以告诉你用于创建它的 Java 程序和用于编写它的 xcode 环境都在 Mac 上。我也知道这不是 Big Endian/Little Endian 问题,因为当我读取 NSString 时,它会从文件中读取大约 2/3 的正确字符串,而不是所有字符串。
  • 好吧,这至少很高兴知道,但我建议您编辑您的问题以反映这一点,这样其他人就不会花时间思考它。

标签: ios file-io binaryfiles


【解决方案1】:

这不起作用的原因是您将NSData 转换为int 的方式。 bytes 方法返回一个指向实际数据的指针,您需要遵守该指针才能获得实际值(否则您将只获得指针的内存地址)。

我尝试了两种方法:

int test = 64;
NSData *data = [NSData dataWithBytes:&test length:4];
int test2 = (int)[data bytes]; //This gave me 170382992

int test = 64;
NSData *data = [NSData dataWithBytes:&test length:4];
int test2 = *((int *)[data bytes]); //This gave me 64

【讨论】:

  • 所以我的代码应该是 { return *((int *)[_databuffer bytes]); } 那么?
  • 如果我这样做 ^ 我得到一个 nil "address=0x0" 问题。
  • 如果没有数据,NSData 将从bytes 返回nil。你需要检查一下。
  • 经过仔细检查,上面带有规定更改的 readInt 方法返回整数“1936019979”,但这不是存储在那里的值。所以这个修复并没有修复它。 (ps,我知道其中的值存储正确,因为我仍然可以在 java 程序中正确使用该文件。
  • NSLogging数据缓冲区的结果是什么?
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2015-07-19
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多