java代码操作zip文件--读取zip文件

来源:互联网 发布:文明5ige编辑器 Linux 编辑:程序博客网 时间:2024/06/05 19:55
public static void readZip(String path) {        try {            ZipInputStream zin = new ZipInputStream(new FileInputStream(                    "C:\\Users\\zhouwy\\Desktop\\xxx.zip"));            ZipEntry entry;            while ((entry = zin.getNextEntry()) != null) {                System.out.println(entry.getName());                System.out.println(entry.getComment());                System.out.println(entry.getExtra());                zin.closeEntry();            }            zin.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }

但是报了一个异常:

java.lang.IllegalArgumentException: MALFORMED
at java.util.zip.ZipCoder.toString(Unknown Source)
at java.util.zip.ZipInputStream.readLOC(Unknown Source)
at java.util.zip.ZipInputStream.getNextEntry(Unknown Source)
后来检查资料才发现,是由于我的压缩文件内的文件名字有中文,但是更深入的了解是由于编码问题

改为如下代码即可【提供3种方式】:

public class TestZip {    public static void readZipFileTest(String path) {        try {            ZipFile zip = new ZipFile(path, Charset.forName("gbk"));            // windows下自己用winRAR压缩文件            Enumeration<? extends ZipEntry> entrys = zip.entries();            while (entrys.hasMoreElements()) {                ZipEntry entry = entrys.nextElement();                System.out.println(entry.getName());            }            zip.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    public static void readZipStreamTest(String path) {        try {            ZipInputStream zin = new ZipInputStream(new FileInputStream(path),                    Charset.forName("gbk"));            ZipEntry zipEntry = null;            while ((zipEntry = zin.getNextEntry()) != null) {                System.out.println(zipEntry.getName());            }            zin.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    public static void readFileSysytemTest(String path) {        /**         * new HashMap<String, String>() { "encoding":"GBK" }         */        Map<String, String> map = new HashMap<String, String>();        map.put("encoding", "gbk");        try {            FileSystem fs = null;            for (FileSystemProvider provider : FileSystemProvider                    .installedProviders()) {                try {                    fs = provider.newFileSystem(Paths.get(path), map);                } catch (UnsupportedOperationException uoe) {                }            }            Files.walkFileTree(fs.getPath("/"), new SimpleFileVisitor<Path>() {                public FileVisitResult visitFile(Path file,                        BasicFileAttributes attrs) throws IOException {                    System.out.println(file.getFileName());                    return FileVisitResult.CONTINUE;                }            });        } catch (IOException e) {            e.printStackTrace();        }    }}

前两中很简单,就是编码改为gbk读取,因为java默认为utf-8.最后一种解释一下,

我是查看的java 核心技术这本书,里面介绍了这个文件系统的方法。但是依然有编码问题,我查看了源代码,后根据源代码改写的,原来的java源代码:

public static FileSystem newFileSystem(Path path,                                           ClassLoader loader)        throws IOException    {        if (path == null)            throw new NullPointerException();        Map<String,?> env = Collections.emptyMap();        // check installed providers        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {            try {                return provider.newFileSystem(path, env);            } catch (UnsupportedOperationException uoe) {            }        }        // if not found, use service-provider loading facility        if (loader != null) {            ServiceLoader<FileSystemProvider> sl = ServiceLoader                .load(FileSystemProvider.class, loader);            for (FileSystemProvider provider: sl) {                try {                    return provider.newFileSystem(path, env);                } catch (UnsupportedOperationException uoe) {                }            }        }        throw new ProviderNotFoundException("Provider not found");    }
ZipFileSystem(ZipFileSystemProvider arg0, Path arg1, Map<String, ?> arg2)            throws IOException {        this.createNew = "true".equals(arg2.get("create"));      /**这里是关键**/        this.nameEncoding = arg2.containsKey("encoding") ? (String) arg2                .get("encoding") : "UTF-8";        this.useTempFile = Boolean.TRUE.equals(arg2.get("useTempFile"));        this.defaultDir = arg2.containsKey("default.dir") ? (String) arg2                .get("default.dir") : "/";        if (this.defaultDir.charAt(0) != 47) {            throw new IllegalArgumentException("default dir should be absolute");        } else {            this.provider = arg0;            this.zfpath = arg1;            if (Files.notExists(arg1, new LinkOption[0])) {                if (!this.createNew) {                    throw new FileSystemNotFoundException(arg1.toString());                }                OutputStream arg3 = Files.newOutputStream(arg1,                        new OpenOption[] { StandardOpenOption.CREATE_NEW,                                StandardOpenOption.WRITE });                Throwable arg4 = null;                try {                    (new ZipFileSystem.END()).write(arg3, 0L);                } catch (Throwable arg13) {                    arg4 = arg13;                    throw arg13;                } finally {                    if (arg3 != null) {                        if (arg4 != null) {                            try {                                arg3.close();                            } catch (Throwable arg12) {                                arg4.addSuppressed(arg12);                            }                        } else {                            arg3.close();                        }                    }                }            }            arg1.getFileSystem().provider()                    .checkAccess(arg1, new AccessMode[] { AccessMode.READ });            if (!Files.isWritable(arg1)) {                this.readOnly = true;            }            this.zc = ZipCoder.get(this.nameEncoding);            this.defaultdir = new ZipPath(this, this.getBytes(this.defaultDir));            this.ch = Files.newByteChannel(arg1,                    new OpenOption[] { StandardOpenOption.READ });            this.cen = this.initCEN();        }    }

显然我们只能改写代码传入编码。

但是依然有个遗留的很严重的问题?

我待文件是按照UTF-8编码的,为什么压缩后的压缩文件得按照GBk去读取??????

11:32:57  2016-07-31

0 0
原创粉丝点击