NSURLResponse的获取filename

it2023-07-13  69

NSURLResponse的suggestedFilename中文乱码问题

 

在使用NSURLConnection下载文件时,如果通过NSURLResponse 类的 suggestedFilename 方法获取文件名,

中文的文件名会遇到乱码问题,这是因为suggestedFilename是解析 HTTP 首部中的 Content-Disposition 域里的 filename 部分实现的,

而很多中文网站此处都是用的GB码,如下面这个头部:

 

 

其中的ce d2 c3 c7就是中文“我们”的GBK码,但是代码中取出来却发现是乱码,如下

 

 

其实,这是因为NSURLResponse 把 Content-Disposition 中的 filename 当成 ASCII 处理了,怪不得会乱码。

可是也不能怪 NSURLResponse,毕竟服务器没有提供任何编码的信息,而 RFC 2183 中也明确说明,不应该在 filename 中使用任何 ASCII 以外的字符,用了就是后果自负了。

有篇文章也提到了这个问题,Cocoa 的 NSString 解码错误处理,但是它的解决方法并不正确,

内存中的值并不是gbk码,

 

 

经过多次尝试,终于找到正确解码的方法,

NSString *fileName,*str;

 

const char *byte = NULL;

 

 

fileName = [response suggestedFilename];

byte = [fileName cStringUsingEncoding:NSISOLatin1StringEncoding];

NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);

str = [[NSString alloc] initWithCString:byte encoding: enc]; //如是utf,此处应改为NSUTF8StringEncoding

 

 

 

另附

 

iphone中编码转换方法

我们可以使用以下方法进行编码转换 NSString* str2 = [NSString stringWithCString:str1 encoding:enc1]; 再调用NSString的cStringUsingEncoding:enc2实现从enc1到enc2的转换 但是获取enc枚举值是个难题 1. NSString.h中只定义了以下编码值 enum {     NSASCIIStringEncoding = 1,                /* 0..127 only */     NSNEXTSTEPStringEncoding = 2,     NSJapaneseEUCStringEncoding = 3,     NSUTF8StringEncoding = 4,     NSISOLatin1StringEncoding = 5,     NSSymbolStringEncoding = 6,     NSNonLossyASCIIStringEncoding = 7,     NSShiftJISStringEncoding = 8,          /* kCFStringEncodingDOSJapanese */     NSISOLatin2StringEncoding = 9,     NSUnicodeStringEncoding = 10,     NSWindowsCP1251StringEncoding = 11,    /* Cyrillic; same as AdobeStandardCyrillic */     NSWindowsCP1252StringEncoding = 12,    /* WinLatin1 */     NSWindowsCP1253StringEncoding = 13,    /* Greek */     NSWindowsCP1254StringEncoding = 14,    /* Turkish */     NSWindowsCP1250StringEncoding = 15,    /* WinLatin2 */     NSISO2022JPStringEncoding = 21,        /* ISO 2022 Japanese encoding for e-mail */     NSMacOSRomanStringEncoding = 30,     NSUTF16StringEncoding = NSUnicodeStringEncoding,      /* An alias for NSUnicodeStringEncoding */ #if MAC_OS_X_VERSION_10_4 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_2_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED     NSUTF16BigEndianStringEncoding = 0x90000100,          /* NSUTF16StringEncoding encoding with explicit endianness specified */     NSUTF16LittleEndianStringEncoding = 0x94000100,       /* NSUTF16StringEncoding encoding with explicit endianness specified */     NSUTF32StringEncoding = 0x8c000100,                        NSUTF32BigEndianStringEncoding = 0x98000100,          /* NSUTF32StringEncoding encoding with explicit endianness specified */     NSUTF32LittleEndianStringEncoding = 0x9c000100        /* NSUTF32StringEncoding encoding with explicit endianness specified */ #endif }; 难道iphone中中文还不支持?不会吧? 2. iphone中肯定是支持中文的,只是NSString中没有定义这个枚举值,我们可以通过两种方法获得这个枚举值 第一个方法是通过CFStringConvertEncodingToNSStringEncoding 比如:NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); NSString* str2 = [NSString stringWithCString:str1 encoding:enc]; 全部的kCFStringEncoding定义参考CFStringEncodingExt.h 另外CFStringConvertIANACharSetNameToEncoding也很有用 3. 另外一种方法是通过 const NSStringEncoding *encodings = [NSString availableStringEncodings]; NSMutableString *str = [[NSMutableString alloc] init]; NSStringEncoding encoding; while ((encoding = *encodings++) != 0) {          [str appendFormat: @"%@ === %in", [NSString localizedNameOfStringEncoding:encoding], encoding]; } 然后打印str数组,你就可以知道每一个encoding的枚举值为多少了,比如中文的为-2147482063

 

最新回复(0)