private static String getUTF8String(byte[] b, int off, int len) {
// First, count the number of characters in the sequence
int count = 0;
int max = off + len;
int i = off;
while (i < max) {
int c = b[i++] & 0xff;
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
count++;
break;
case 12: case 13:
// 110xxxxx 10xxxxxx
if ((int)(b[i++] & 0xc0) != 0x80) {
throw new IllegalArgumentException();
}
count++;
break;
case 14:
// 1110xxxx 10xxxxxx 10xxxxxx
if (((int)(b[i++] & 0xc0) != 0x80) ||
((int)(b[i++] & 0xc0) != 0x80)) {
throw new IllegalArgumentException();
}
count++;
break;
default:
// 10xxxxxx, 1111xxxx
throw new IllegalArgumentException();
}
}
if (i != max) {
throw new IllegalArgumentException();
}
// Now decode the characters...
char[] cs = new char[count];
i = 0;
while (off < max) {
int c = b[off++] & 0xff;
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
cs[i++] = (char)c;
break;
case 12: case 13:
// 110xxxxx 10xxxxxx
cs[i++] = (char)(((c & 0x1f) << 6) | (b[off++] & 0x3f));
break;
case 14:
// 1110xxxx 10xxxxxx 10xxxxxx
int t = (b[off++] & 0x3f) << 6;
cs[i++] = (char)(((c & 0x0f) << 12) | t | (b[off++] & 0x3f));
break;
default:
// 10xxxxxx, 1111xxxx
throw new IllegalArgumentException();
}
}
return new String(cs, 0, count);
}
以上是ZipInputStream读取有中文条目的zip包时会抛出异常的方法,该方法有两个while循环,第一个是统计条目名 字符数count,第二个是用UTF-8算法解码byte数组,提取到字符串 一切不是UTF-8的字符串直接抛异常,由于中文系统默认编码是GBK 所以条目名含有中文时直接抛异常。
不知道编码是提倡用循环统计 还是“变长数组”,该方法可以改成如下:
private static String getUTF8String(byte[] b, int off, int len) {CharArrayWriter caw=new CharArrayWriter();
int i = 0;
while (off < max) {
int c = b[off++] & 0xff;
switch (c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// 0xxxxxxx
caw.append((char) c);
break;
case 12:
case 13:
// 110xxxxx 10xxxxxx
//
caw.append((char) (((c & 0x1f) << 6) | (b[off++] & 0x3f)));
break;
case 14:
// 1110xxxx 10xxxxxx 10xxxxxx
int t = (b[off++] & 0x3f) << 6;
//
caw.append((char) (((c & 0x0f) << 12) | t | (b[off++] & 0x3f)));
break;
default:
// 10xxxxxx, 1111xxxx
throw new IllegalArgumentException();
}
}
char[] ch=caw.toCharArray();
return new String(ch, 0, ch.length);
}
也就是把统计字符数改成CharArrayWriter类,利用它的“数组扩展特性”,该类默认分配初始数组为32大小,个人认为是比较合理的。不知各位比较支持哪种编程方法。
其次我们再来讨论乱码的问题。其实String类里面就封装了byte解码的功能了,这里不知道作者为什么要自己实现解码,还不负责任的抛异常 难道是想表现一下自己的技术?用字符串的解码 可以改成如下:
private static String getUTF8String(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
{
try{
return new String(paramArrayOfByte, paramInt1, paramInt2,"UTF-8");
}catch(UnsupportedEncodingException e){
e.printStackTrace();
return "encoding error!";
}
}
怎么样,够简单吧。
为了能够让用户自行设置编码,可以增加一个成员变量,增加一个方法 于是改成这样:
private static String filenameEncoding=Charset.defaultCharset().toString();//默认使用系统默认编码
public static void setFilenameEncoding(String encoding){
filenameEncoding=encoding;
}
private static String getUTF8String(byte[] b, int off, int len) {
{
try{
return new String(paramArrayOfByte, paramInt1, paramInt2,filenameEncoding);
}catch(UnsupportedEncodingException e){
e.printStackTrace();
return "encoding error!";
}
}
这样就“完美”了。
后记:以上代码楼主亲自测过功能没有问题 不过不知道为什么SUN不写成这样,写此博文旨在跟大家交流,楼主的语文学得不好 尽请见谅 希望大家能看懂意思并发表意见就好了。
分享到:
相关推荐
1、文件解压zip通用机制方法、一行代码支持中文; 2、一行代码解决 java.util.zip.ZipInputStream 中文乱码; 3、删除指定路径内的所有文件通用机制方法;
对jdk内置的zip解压缩存在bug 如果zip文件里有中文文件,会报错 现在把这个问题解决。
JAVA中文件压缩引起的乱码问题,是由于Java编码以Unicode 为基础的,所以ZipOutputStream(还有ZipInputStream) 处理压缩工作时,就以Unicode来处理中文。 所以为了能在压缩(或解压)时,不让其产生乱码问题,就得...
项目中碰到问题.jdk zipEntry 压缩中文文件名乱码 上网查了下,有两种方法,一种修改jdk ZipInputStream及ZipOutputStream 的源文件,比较麻烦,不建议此项. 第二种 就是拿来主义,因为 开源项目 Ant 里已经有...
java实现文件解压缩,ZipInputStream,ZipOutputStream
因为本人工作需要解压文件,但是出现中文乱码,但是又不想用ant.jar 所以就只有将zipInputStream更改。当然我是转载别人的,经测试可以使用哦,哈哈 http://zwllxs.iteye.com/blog/871260 这是地址
基于GUI用IO流中的ZipOutputStream ,ZipInputStream实现文件的解压与压缩, 如文件解压函数如下 private void unZip(String zipFileName, String outputDirectory)throws Exception { InputStream in=null; ...
通过对JDK的java.util.zip下的ZipInputStream和ZipOutputStream类进行改造,彻底解决压缩和解压缩文件时的中文文件名乱码问题。 包含已大好的jar包,以及一个如何使用的Demo程序。
支持android和java加密压缩、解压封装好的类库,代码可以参考http://www.cnblogs.com/cmf34263/ 【java加密解压类库】文章
有些时候需要替换zip内的文件。 网上的办法大多是——先解压,然后对解压目录替换文件,最后再重新压缩。该办法需要比较繁琐,且需要一个临时目录...后来找到利用 ZipInputStream、ZipOutputStream 实现该功能的办法。
C# WPF 解压缩7zip文件 带进度条 sevenzipsharp WPF PNG实现的图形进度条 .NET 3.5 vs2013打开 来这里看介绍 http://www.cnblogs.com/xe2011/p/3761870.html
通过ZipOutputStream和ZipInputStream实现了zip压缩功能.
excel大数量导出理论以及ZipOutputStram与ZipInputStream使用
可以实现文件的压缩和解压 ZipFile zipInputStream ZipEntry zipOutputStream
前端上传ZIP压缩文件 使用 ZipInputStream 来解压至指定目录中.
ZipInputStream s = new ZipInputStream(File.OpenRead(filePath1)); ZipEntry theEntry; while ((theEntry = s.GetNextEntry()) != null) { string fullname = Server.MapPath("ziptemp/" + urlid + "/" + the...
减少频繁发送的问题。缺点:文件大小会变大,如果传输过程中断了,风险较大。 三、开发工具为:JDK1.8, idea ZIP是一种较为常见的压缩形式,在Java中要想实现ZIP的压缩需要导入java.util.zip包,可以使用此包中的...
ZipInputStream zis=new ZipInputStream(is); ProcessDefinition pd=ProcessDefinition.parseParZipInputStream(zis); //需要使用jc的方法吧pd持久到数据库中 jc.deployProcessDefinition(pd); jc.close(); } ...
我已经重新编译过了,解决了该问题。 解决方法:在项目所引用库“ICSharpCode.SharpZipLib.dll”的ICSharpCode.SharpZipLib.Zip.Compression. ZipInputStream.cs类中找到抛出异常的代码段: int BodyRead(byte[] ...
压缩的实现比较容易,下面介绍利用ZipEntry、ZipInputStream和ZipOutputStream三个Java 类实现zip数据压缩方式的编程方法。 zip压缩文件结构:一个zip文件由多个entry组成,每个entry有一个唯一的名称,entry的 ...