You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS App将TCP接收的十六进制字符串转.tgz文件损坏问题求助

问题根因
  • 现有第一种转换逻辑(HEX转NSString再转NSData)不适用于二进制文件场景:tgz为二进制压缩格式,字节值覆盖0x00-0xFF全范围,超出ASCII、UTF8等文本编码的安全映射区间,强制转NSString会出现字节截断、值错乱,生成文件必然损坏。
  • 现有第二种HEX直接转NSData的实现存在逻辑错误:64位iOS系统下unsigned long类型占8字节,原实现每次调用appendBytes:&wholeByte length:2时,会为每个解析出的单字节额外拼接1个0x00空字节,最终文件长度为正常值的2倍,格式完全破坏。
  • 提供的待转换HEX串本身合法:串首1F8B08为gzip格式标准文件头,符合tgz文件特征,无需调整编码方案,仅需修复HEX转二进制逻辑即可正常生成文件。
修复后的代码实现

替换原有错误的转换方法,调整文件写入逻辑:

// 正确的HEX字符串转二进制NSData方法
+ (NSData *)dataFromHexString:(NSString *)hexString {
    // 预处理:过滤TCP传输可能带入的空格、换行等非十六进制字符
    NSCharacterSet *hexChars = [NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"];
    NSString *cleanHex = [[hexString componentsSeparatedByCharactersInSet:hexChars.invertedSet] componentsJoinedByString:@""];
    NSUInteger len = cleanHex.length;
    // 奇数长度补前导0做字节对齐
    if (len % 2 != 0) {
        cleanHex = [@"0" stringByAppendingString:cleanHex];
        len += 1;
    }
    NSMutableData *resultData = [NSMutableData dataWithCapacity:len/2];
    const char *cStr = [cleanHex cStringUsingEncoding:NSASCIIStringEncoding];
    for (NSUInteger i = 0; i < len; i += 2) {
        // 用uint8_t单字节类型存储解析结果,避免多字节类型写入冗余数据
        uint8_t byte = (uint8_t)(strtoul((char[]){cStr[i], cStr[i+1], '\0'}, NULL, 16) & 0xFF);
        [resultData appendBytes:&byte length:1];
    }
    return [resultData copy];
}

// 修复后的tgz文件写入方法
+ (void)writeToLogFile:(NSString*)hexContent fileName:(NSString*)fileNameString{
    // 使用苹果官方推荐的沙盒路径获取方式,避免硬编码路径拼接的兼容性问题
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileNameString];
    // 直接通过HEX转二进制得到tgz数据,不经过NSString文本类型中转
    NSData *tgzData = [self dataFromHexString:hexContent];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        NSError *error = nil;
        [tgzData writeToFile:filePath options:NSDataWritingAtomic error:&error];
        if (error) {
            NSLog(@"tgz文件写入失败: %@", error.localizedDescription);
        } else {
            // 写入完成后校验gzip文件魔数,快速确认格式正确性
            NSData *headerCheck = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:nil];
            const uint8_t *bytes = headerCheck.bytes;
            if (headerCheck.length >=2 && bytes[0] == 0x1F && bytes[1] == 0x8B) {
                NSLog(@"tgz文件写入成功,格式头校验通过");
            }
        }
    });
}
注意事项
  • 所有二进制文件(压缩包、图片、音视频等)的HEX转存操作,都要直接生成NSData类型,禁止通过NSString做中间编码转换,否则必然出现字节损坏。
  • 上述代码完全兼容Xcode 13.1、iOS 15.1+的开发环境,无需额外适配。用提供的测试HEX串转换后,生成的文件可正常解压使用。

内容的提问来源于stack exchange,提问作者madhav kure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 20:30:45