中文名过长导致文件下载失败问题的解决

    关于中文文件下载的问题,网上的咨询和答疑已经很多,我原来处理下载的代码如下:
    
    response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
 下载的程序里有了这句,一般在IE6的下载提示框上将正确显示文件的名字,无论是简体中文,还是日文。不过当时确实没有仔细测试文件名很长的中文文件名。先如今经过仔细测试,发现文字只要超过17个字,就不能下载了。经过好一番google和反复测试,总算对这个问题有了系统的认识,分列如下:

     . 通过我原来的方式,也就是先用URLEncoder编码,当中文文字超过17个时,IE6 无法下载文件。这是IE的bug,参见微软的知识库文章 KB816868 。原因可能是因为ie在处理 Response Header 的时候,对header的长度限制在150字节左右。而一个汉字编码成UTF-8是9个字节,那么17个字便是153个字节,所以便会报错。微软提供了一个补丁,可以从 这里 下载。这个补丁需要先安装ie6 sp1。因为我平时勤打补丁,我的IE6版本号是 6.0.2800.1106.xpsp2_xxxxx。所以我可能已经安装过了补丁,从而可以下载,但仍然出现文件名被截断的现象。微软让我们等待IE下一个service pack的发布。我今天也上网看到了好消息,迫于firefox的压力,IE7可能在年中发布。另外,Firefox 不支持这样的方式,将把编码后的%xx%xx直接作为文件名显示。


     . 我尝试使用 javamail 的MimeUtility.encode()方法来编码文件名,也就是编码成 =?gb2312?B?xxxxxxxx?= 这样的形式,并从 RFC1522 中找到对应的标准支持。不过很遗憾,IE6并不支持这一个标准。我试了一下,Firefox是支持的。

     . 按网上很多人提供的解决方案:将文件名编码成ISO8859-1似乎是有效的解决方案,代码如下:
    
    response.setHeader( "Content-Disposition", "attachment;filename="  + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) );
    
    在确保附件文件名都是简体中文字的情况下,那么这个办法确实是最有效的,不用让客户逐个的升级IE。如果台湾同胞用,把gb2312改成big5就行。但现在的系统通常都加入了国际化的支持,普遍使用UTF-8。如果文件名中又有简体中文字,又有繁体中文,还有日文。那么乱码便产生了。另外,在我的电脑上Firefox(v1.0-en)下载也是乱码。

    折中考虑,我结合了一、三的方式,代码片断如下:

        String fileName = URLEncoder.encode(atta.getFileName(), "UTF-8");
        /*
         * see http://support.microsoft.com/default.aspx?kbid=816868
         */
        if (fileName.length() > 150) {
            String guessCharset = xxxx /*根据request的locale 得出可能的编码,中文操作系统通常是gb2312*/
            fileName = new String(atta.getFileName().getBytes(guessCharset), "ISO8859-1");
        }
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        
    暂且不考虑 Firefox 是因为它目前似乎还没有有力侵食到IE的企业用户市场。影响客户买单的常常是进度,而不是兼容度。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Product Name : NT Locale Emulator Advance (NT全域通) short for NTLEA Component Description: ntlea.exe - NTLEA GUI shell and shortcut launcher ntleac.exe - NTLEA core launcher ntleah.dll - NTLEA remote injection DLL ntleap.dll - NTLEA helper library neko.dll - NTLEA GUI runtime library Version & Update History : NTLEA Core 0.86 Beta 07.6.13 by LOVEHINA-AVC 增加对GetSystemDefaultUILanguage及GetUserDefaultUILanguage函数的挂钩 改善了Computer-based Training钩子的挂钩方式 修正了其他一些细小的BUG NTLEA Core 0.85 Beta 07.6.9 by LOVEHINA-AVC 增加让NTLEA加载的应用程序不受系统SDB补丁机制影响的功能 修正了其他一些细小的BUG NTLEA Core 0.83 Beta 07.6.8 by LOVEHINA-AVC 修正了之前的版本不能让含有特殊字符路径的应用程序正常工作的问题 修正了其他一些细小的BUG NTLEA GUI Launcher 1.0 Final 07.6.7 by 七夜真神 增加多语系界面支持与对应的区码(目前支持简体中文、繁体中文及英文) NTLEA Core 0.82 Beta 07.6.7 by LOVEHINA-AVC 修正了在一部分程序下执行会发生初始化失败问题 完善了跨进程跟踪注入的功能 增加直接打开任意扩展名文件的功能(注:若系统中启用了Microsoft Applocale,msi安装程序将无法被NTLEA正确加载) 0.80 beta 07.6.4 中文名称更改为“NT全域通” 修正了对话框处理函数不能被正确挂钩的问题 修正了因错误地址传递导致应用程序启动失败问题 修正了一部分程序不能使用IME标准输入法的问题 修正了0.72~0.75版不能在Windows 2000及Windows XP SP0 SP1下运行的问题 增加WM_CHAR及WM_IME_CHAR消息的处理模块,修正了输入框文字不能被正确显示及文字不能被正确输入的问题 消除了数个读零地址非法操作的诱发因素 改进了消息钩子的处理方式 增加应用程序参数指定的支持(详见命令行选项说明) 增加重新指定字体大小的功能(详见命令行选项说明) 修正了Core Launcher(NTLEAC)不能引导一部分程序的问题 修正了多个细小的BUG 0.75 beta 07.1.10 修正了0.73版不能支持某些Unicode/ANSI混合型应用程序的问题 ntleac命令行模式“F”选项实装(注:若要强制指定应用程序所使用的字体,则至少需追加“P4”选项) 增加LB_GETTEXTLEN消息的处理模块(感谢Yoxola提供兼容性问题报告) 0.73 beta 06.12.16 修正了一部分程序在通过系统模版创建窗口时无法被正确挂钩的问题 0.72 beta 06.12.4 修正了在Visual C++ MFC框架程序中会产生乱码的兼容性问题 修正了在调用对话框模版函数后程序运行不正常的问题 增加对kernel32!CreateProcessW函数的挂勾 0.70 beta 06.11.30 增加以下针对窗口及消息处理函数的挂钩: user32!SetWindowTextA user32!GetWindowTextA user32!SendMessageA user32!SendMessageTimeoutA user32!SendMessageCallbackA user32!SendNotifyMessageA user32!PostMessageA user32!GetWindowLongA user32!SetWindowLongA user32!DefDlgProcA user32!DefFrameProcA user32!DefMDIChildProcA user32!DialogBoxParamA user32!DialogBoxIndirectParamA user32!CreateDialogParamA user32!CreateDialogIndirectParamA 增加其它的一些函数的挂钩: user32!GetMenuStringA user32!GetMenuItemInfoA user32!SetMenuItemInfoA kernel32!CharPrevA kernel32!CharNextA kernel32!IsDBCSLeadByte gdi32!EnumFontFamiliesExA gdi32!CreateFontIndirectA 增加自定义右键启动菜单的功能 增加指定预设字体的功能 0.52 beta 06.10.14 增加对user32!CreateWindowExA函数的挂钩 增加对user32!DefWindowProcA函数的挂钩 修正了VerQueryValueA挂钩函数在Windows XP SP0及SP1下会导致无效内存访问异常的问题 0.50 beta 06.10.12 增加对kernel32!GetCommandLineA函数的挂钩 修正了ntdll!RtlUnicodeToMultibyteN挂钩函数中一个重大的BUG,解决了大部分程序的兼容性问题 0.20 beta 06.10.9 增加针对特定应用程序的支持选项 重写部分函数,提高了挂勾程序的兼容性 修正数个小BUG 0.17 beta 06.9.30 再次(?)完善了kernel32!CreateProcessA挂钩函数的功能 0.16 beta 06.9.28 修正在目标程序调用version!VerQueryValueA时可能构成死循环的BUG 0.15 beta 06.9.27 增加对kernel32!GetTimeZoneInformation函数的挂钩,新增时区修正参数 增加对version!VerQueryValueA函数的挂勾 增加对Windows XP SP0操作系统的支持 新增一个兼容性选项 去除了不必要的语言ID参数 完善了kernel32!CreateProcessA挂钩函数的功能 0.11 beta 06.9.25 启动程序ntleac.exe与挂钩程序ntleah.dll由ANSI版本转变为Unicode版 注:如果在使用NTLEA外壳时发现程序无法启动,可尝试直接运行ntleac.exe 附:ntleac参数说明(第一个参数必须包含双引号): 1. "x:\xxxxx\xxx.exe" 说明:目标程序路径。该参数必须位于第一项。 2. "Px" 说明:指定兼容性选项。x为描述兼容性开关的数值,每一个位域指定一个选项(注)。例如,当x为1时,第1个兼容性选项将被开启;当x为8时,第4个兼容性选将被开启;当x为7时,前3个兼容性选项均被开启(1 | 2 | 4 = 7)。 注:这里所说的位域是指二进制数的数位,一个整数最多拥有32个位域,第x位域的值等于2的x次方。 3. "Cx" 说明:指定页码。x为页码ID。 4. "Lx" 说明:指定语言。x为语言区域ID。 5. "Tx" 说明:指定时区修正。x为UTC时区修正数值,单位是分钟。 6. "Fxxx" 说明:指定预设字体,xxx为字体名称。 7. "Axxx" 说明:指定将要传给目标应用程序的参数,xxx为参数内容。 8. "Sx" 说明:指定字体的收放比率,x为比值,单位是百分率。 示例: ntleac.exe "d:\test\game.exe" "A-G 123 -B 456" "P0" "C932" "L1041" "T-540" "FMS Gothic" "S200" 执行结果为启动“d:\test\game.exe -G 123 -B 456”,并设置页码为932(日文Shift-JIS),语言区域为日本,字体为“MS Gothic”,以两倍的大小显示,时区为东9区(GMT + 9:00或UTC - 9:00)。 (注:如果参数中包含双引号,则可用单引号来代替。如上例的"A-G 123 -B 456",追加双引号后可书写为"A'-G 123' '-B 456'") 0.10 beta 06.9.25 正式更名为NT Locale Emulator Advance 增加具有图形界面的外壳程序 增加跨进程跟踪功能 0.05 beta 06.9.24 修正了0.04 beta无法在Windows 2000及XP SP1下运行的问题 0.04 beta 06.9.24 增加对kernel32!CompareStringA函数的挂钩 增加对ntdll!RtlUnicodeToMultibyteN函数的挂钩 0.03 beta 06.9.24 增加对kernel32!CreateFileA函数的本地化支持 修正了前一个版本在多处理器系统中可能出现的兼容性问题 0.02 beta 06.9.23 修正了无法在Windows XP SP1下运行的问题 0.01 beta 06.9.22 最初的版本 FAQs Q:这个工具能够做什么? A:区域模拟,以及内码转换。一些应用程序可能无法在其它的区域模拟软件下正常运行,因此我编写了这个工具,以避免手工转换系统语言区域所带来的麻烦。 Q:它的兼容性如何? A:该程序能够在Windows 2000 SP4/XP及2003 SP1下正常工作,但它很可能不支持Windows 2000 SP3及更低的版本。(注意,当前的版本不支持Windows 20003 Gold、即SP0) 目前已测试可以支持的操作系统详细列表: Windows 2000 SP4 Windows XP Windows XP SP1 Windows XP SP2 Windows Server 2003 SP1 Windows XP x64 Edition Windows Vista Q:使用这个工具时需要安装额外的软件吗? A:不需要。同时这个程序也是绿色软件。 Q:我看到了两个可执行文件,应该怎样使用它们? A:直接运行ntleac.exe,或者为它建立一个快捷方式,并在命令行的末尾填上目标程序的全路径名。关于参数的详细说明请参考附录,在新的版本中您还可以使用名为NTLEAGUI的外壳程序。 Q:我可以与他人分享这个软件吗? A:是的,您可以自由转载这个程序,但请务必保持其完整,且不要修改任何内容。
当解压缩zip文件中含有中文名的文件时,可能会出现乱码或者解压失败问题。这是因为在压缩文件时,文件名使用了默认编码格式,而在解压缩时,解压软件使用了不同的编码格式,导致文件名解析错误。 为了解决这个问题,可以通过指定解压缩文件名的编码格式来解决。以下是一个Java程序示例,用于解压缩zip文件并处理中文文件名的编码问题: ```java import java.io.*; import java.util.*; import java.util.zip.*; public class ZipUtils { public static void unzip(File zipFile, File destDir, String charset) throws IOException { if (!destDir.exists()) { destDir.mkdirs(); } ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFile), Charset.forName(charset)); ZipEntry entry; byte[] buffer = new byte[1024]; while ((entry = zipIn.getNextEntry()) != null) { String fileName = entry.getName(); if (entry.isDirectory()) { File subDir = new File(destDir, fileName); subDir.mkdirs(); continue; } File file = new File(destDir, fileName); File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } OutputStream out = new FileOutputStream(file); int len; while ((len = zipIn.read(buffer)) > 0) { out.write(buffer, 0, len); } out.close(); } zipIn.close(); } } ``` 在调用此方法时,可以指定解压缩文件名的编码格式,例如: ```java ZipUtils.unzip(new File("sun.zip"), new File("destDir"), "GBK"); ``` 这里的编码格式使用了GBK,根据实际情况可以修改为其他编码格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值