NSURLResponse的suggestedFilename中文乱码问题

原创 2012年03月22日 14:55:16

在使用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 allocinitWithCString: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


版权声明:本文为博主原创文章,未经博主允许不得转载。

response.suggestedFilename返回和服务器的文件名一样

  • baohanqing
  • baohanqing
  • 2016年04月17日 08:28
  • 1244

取HTTP response的suggestedFilename中文乱码问题

当我们在进行网络请求时,比如下载文件,用原生的网络请求或者第三方网络请求框架的时候,若要从response的header里面取filename,我们会发现,如果访问的url里面带有中文,拿到的file...
  • charles910921
  • charles910921
  • 2016年05月20日 14:31
  • 580

下载文件思路

下载文件直接请求获取: 这种方式会将数据全部接收回来,然后一次性存储到文件中,会出现内存峰值问题,也没有进度跟进 //ViewController.h#import @interface ViewCo...
  • u010545519
  • u010545519
  • 2016年05月11日 14:14
  • 3079

文件下载的三种方式,看这里就已经足够了。

大文件的断点续传,多种方式的详细解析,可以满足你的需求。
  • fuzongjian
  • fuzongjian
  • 2016年05月05日 19:44
  • 5670

如何解决tomcat启动闪退问题

在这几天,遇到一个Tomcat启动闪退的问题,通过查阅各种资料,算是完美解决。在此分享给朋友们。         首先,确定你的问题在哪里         1.查询错误:win+R 输入c...
  • cs15229216584
  • cs15229216584
  • 2016年12月28日 17:06
  • 12254

Tomcat启动一半闪退问题解决

最近刚刚接触Tomcat,对其还不是很了解。在这几天,遇到一个Tomcat启动闪退的问题,通过查阅各种资料,算是完美解决。在此分享给朋友们。         首先,确定你的问题在哪里。有两个方法,...
  • lu930124
  • lu930124
  • 2015年07月22日 09:49
  • 16272

iOS 文件下载 (AFNetwork 三方框架 文件名中文字符乱码问题解决)四

很久以前,就把这篇文章的andriod部分和服务器部分搞定,最近论文送审途中,于是写了几行简单的代码如下。 把AFNetwork拿来做一下。具体代码如下: -(void)download { ...
  • nothingl3
  • nothingl3
  • 2015年04月12日 20:44
  • 1750

javaweb之response实现文件下载(文件名是中文名需要经过url编码)

package test.response; import java.io.FileInputStream; import java.io.IOException; import java.io.I...
  • wuer0520
  • wuer0520
  • 2014年03月06日 15:56
  • 8388

MongoDB mongo.exe启动及闪退解决

启动: 进入MongoDB安装目录下的bin目录,启动mongod.exe  出现如图所示的提示行,打开点击打开链接 It looks like you are trying to access M...
  • Wyx_wx
  • Wyx_wx
  • 2017年07月26日 09:58
  • 1861

iOS 启动连续闪退保护方案

iOS 启动连续闪退保护方案
  • songchunmin_
  • songchunmin_
  • 2016年06月02日 19:44
  • 895
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:NSURLResponse的suggestedFilename中文乱码问题
举报原因:
原因补充:

(最多只允许输入30个字)