src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java

Print this page




 595             if (e.mtime == -1)
 596                 e.mtime = System.currentTimeMillis();
 597             if (e.method == -1)
 598                 e.method = defaultMethod;
 599             // store size, compressed size, and crc-32 in datadescriptor
 600             e.flag = FLAG_DATADESCR;
 601             if (zc.isUTF8())
 602                 e.flag |= FLAG_USE_UTF8;
 603         }
 604 
 605         @Override
 606         public void close() throws IOException {
 607             e.bytes = toByteArray();
 608             e.size = e.bytes.length;
 609             e.crc = -1;
 610             super.close();
 611             update(e);
 612         }
 613     }
 614 




 615     // Returns a Writable/ReadByteChannel for now. Might consdier to use
 616     // newFileChannel() instead, which dump the entry data into a regular
 617     // file on the default file system and create a FileChannel on top of
 618     // it.
 619     SeekableByteChannel newByteChannel(byte[] path,
 620                                        Set<? extends OpenOption> options,
 621                                        FileAttribute<?>... attrs)
 622         throws IOException
 623     {
 624         checkOptions(options);
 625         if (options.contains(StandardOpenOption.WRITE) ||
 626             options.contains(StandardOpenOption.APPEND)) {
 627             checkWritable();
 628             beginRead();    // only need a readlock, the "update()" will obtain
 629                             // thewritelock when the channel is closed
 630             try {
 631                 ensureOpen();
 632                 Entry e = getEntry(path);
 633                 if (e != null) {
 634                     if (e.isDir() || options.contains(CREATE_NEW))


 636                     SeekableByteChannel sbc =
 637                             new EntryOutputChannel(new Entry(e, Entry.NEW));
 638                     if (options.contains(APPEND)) {
 639                         try (InputStream is = getInputStream(e)) {  // copyover
 640                             byte[] buf = new byte[8192];
 641                             ByteBuffer bb = ByteBuffer.wrap(buf);
 642                             int n;
 643                             while ((n = is.read(buf)) != -1) {
 644                                 bb.position(0);
 645                                 bb.limit(n);
 646                                 sbc.write(bb);
 647                             }
 648                         }
 649                     }
 650                     return sbc;
 651                 }
 652                 if (!options.contains(CREATE) && !options.contains(CREATE_NEW))
 653                     throw new NoSuchFileException(getString(path));
 654                 checkParents(path);
 655                 return new EntryOutputChannel(
 656                     new Entry(path, Entry.NEW, false, defaultMethod));
 657 
 658             } finally {
 659                 endRead();
 660             }
 661         } else {
 662             beginRead();
 663             try {
 664                 ensureOpen();
 665                 Entry e = getEntry(path);
 666                 if (e == null || e.isDir())
 667                     throw new NoSuchFileException(getString(path));
 668                 try (InputStream is = getInputStream(e)) {
 669                     // TBD: if (e.size < NNNNN);
 670                     return new ByteArrayChannel(is.readAllBytes(), true);
 671                 }
 672             } finally {
 673                 endRead();
 674             }
 675         }
 676     }


 704                         throw new FileAlreadyExistsException(getString(path));
 705                     }
 706                     if (e.isDir())
 707                         throw new FileAlreadyExistsException("directory <"
 708                             + getString(path) + "> exists");
 709                 }
 710                 options = new HashSet<>(options);
 711                 options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
 712             } else if (e == null || e.isDir()) {
 713                 throw new NoSuchFileException(getString(path));
 714             }
 715 
 716             final boolean isFCH = (e != null && e.type == Entry.FILECH);
 717             final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
 718             final FileChannel fch = tmpfile.getFileSystem()
 719                                            .provider()
 720                                            .newFileChannel(tmpfile, options, attrs);
 721             final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
 722             if (forWrite) {
 723                 u.flag = FLAG_DATADESCR;
 724                 u.method = METHOD_DEFLATED;
 725             }
 726             // is there a better way to hook into the FileChannel's close method?
 727             return new FileChannel() {
 728                 public int write(ByteBuffer src) throws IOException {
 729                     return fch.write(src);
 730                 }
 731                 public long write(ByteBuffer[] srcs, int offset, int length)
 732                     throws IOException
 733                 {
 734                     return fch.write(srcs, offset, length);
 735                 }
 736                 public long position() throws IOException {
 737                     return fch.position();
 738                 }
 739                 public FileChannel position(long newPosition)
 740                     throws IOException
 741                 {
 742                     fch.position(newPosition);
 743                     return this;
 744                 }


1390         public void write(int b) throws IOException {
1391             out.write(b);
1392             crc.update(b);
1393             written += 1;
1394         }
1395 
1396         @Override
1397         public void write(byte b[], int off, int len)
1398                 throws IOException {
1399             out.write(b, off, len);
1400             crc.update(b, off, len);
1401             written += len;
1402         }
1403 
1404         @Override
1405         public void close() throws IOException {
1406             if (isClosed)
1407                 return;
1408             isClosed = true;
1409             e.size = e.csize = written;
1410             e.size = crc.getValue();
1411         }
1412     }
1413 
1414     // Wrapper output stream class to write out a "deflated" entry.
1415     // (1) this class does not close the underlying out stream when
1416     //     being closed.
1417     // (2) no need to be "synchronized", only used by sync()
1418     private class EntryOutputStreamDef extends DeflaterOutputStream {
1419         private CRC32 crc;
1420         private Entry e;
1421         private boolean isClosed;
1422 
1423         EntryOutputStreamDef(Entry e, OutputStream os) throws IOException {
1424             super(os, getDeflater());
1425             this.e =  Objects.requireNonNull(e, "Zip entry is null");
1426             this.crc = new CRC32();
1427         }
1428 
1429         @Override
1430         public void write(byte b[], int off, int len)




 595             if (e.mtime == -1)
 596                 e.mtime = System.currentTimeMillis();
 597             if (e.method == -1)
 598                 e.method = defaultMethod;
 599             // store size, compressed size, and crc-32 in datadescriptor
 600             e.flag = FLAG_DATADESCR;
 601             if (zc.isUTF8())
 602                 e.flag |= FLAG_USE_UTF8;
 603         }
 604 
 605         @Override
 606         public void close() throws IOException {
 607             e.bytes = toByteArray();
 608             e.size = e.bytes.length;
 609             e.crc = -1;
 610             super.close();
 611             update(e);
 612         }
 613     }
 614 
 615     private int getCompressMethod(FileAttribute<?>... attrs) {
 616          return defaultMethod;
 617     }
 618 
 619     // Returns a Writable/ReadByteChannel for now. Might consdier to use
 620     // newFileChannel() instead, which dump the entry data into a regular
 621     // file on the default file system and create a FileChannel on top of
 622     // it.
 623     SeekableByteChannel newByteChannel(byte[] path,
 624                                        Set<? extends OpenOption> options,
 625                                        FileAttribute<?>... attrs)
 626         throws IOException
 627     {
 628         checkOptions(options);
 629         if (options.contains(StandardOpenOption.WRITE) ||
 630             options.contains(StandardOpenOption.APPEND)) {
 631             checkWritable();
 632             beginRead();    // only need a readlock, the "update()" will obtain
 633                             // thewritelock when the channel is closed
 634             try {
 635                 ensureOpen();
 636                 Entry e = getEntry(path);
 637                 if (e != null) {
 638                     if (e.isDir() || options.contains(CREATE_NEW))


 640                     SeekableByteChannel sbc =
 641                             new EntryOutputChannel(new Entry(e, Entry.NEW));
 642                     if (options.contains(APPEND)) {
 643                         try (InputStream is = getInputStream(e)) {  // copyover
 644                             byte[] buf = new byte[8192];
 645                             ByteBuffer bb = ByteBuffer.wrap(buf);
 646                             int n;
 647                             while ((n = is.read(buf)) != -1) {
 648                                 bb.position(0);
 649                                 bb.limit(n);
 650                                 sbc.write(bb);
 651                             }
 652                         }
 653                     }
 654                     return sbc;
 655                 }
 656                 if (!options.contains(CREATE) && !options.contains(CREATE_NEW))
 657                     throw new NoSuchFileException(getString(path));
 658                 checkParents(path);
 659                 return new EntryOutputChannel(
 660                     new Entry(path, Entry.NEW, false, getCompressMethod(attrs)));
 661 
 662             } finally {
 663                 endRead();
 664             }
 665         } else {
 666             beginRead();
 667             try {
 668                 ensureOpen();
 669                 Entry e = getEntry(path);
 670                 if (e == null || e.isDir())
 671                     throw new NoSuchFileException(getString(path));
 672                 try (InputStream is = getInputStream(e)) {
 673                     // TBD: if (e.size < NNNNN);
 674                     return new ByteArrayChannel(is.readAllBytes(), true);
 675                 }
 676             } finally {
 677                 endRead();
 678             }
 679         }
 680     }


 708                         throw new FileAlreadyExistsException(getString(path));
 709                     }
 710                     if (e.isDir())
 711                         throw new FileAlreadyExistsException("directory <"
 712                             + getString(path) + "> exists");
 713                 }
 714                 options = new HashSet<>(options);
 715                 options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
 716             } else if (e == null || e.isDir()) {
 717                 throw new NoSuchFileException(getString(path));
 718             }
 719 
 720             final boolean isFCH = (e != null && e.type == Entry.FILECH);
 721             final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
 722             final FileChannel fch = tmpfile.getFileSystem()
 723                                            .provider()
 724                                            .newFileChannel(tmpfile, options, attrs);
 725             final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
 726             if (forWrite) {
 727                 u.flag = FLAG_DATADESCR;
 728                 u.method = getCompressMethod(attrs);
 729             }
 730             // is there a better way to hook into the FileChannel's close method?
 731             return new FileChannel() {
 732                 public int write(ByteBuffer src) throws IOException {
 733                     return fch.write(src);
 734                 }
 735                 public long write(ByteBuffer[] srcs, int offset, int length)
 736                     throws IOException
 737                 {
 738                     return fch.write(srcs, offset, length);
 739                 }
 740                 public long position() throws IOException {
 741                     return fch.position();
 742                 }
 743                 public FileChannel position(long newPosition)
 744                     throws IOException
 745                 {
 746                     fch.position(newPosition);
 747                     return this;
 748                 }


1394         public void write(int b) throws IOException {
1395             out.write(b);
1396             crc.update(b);
1397             written += 1;
1398         }
1399 
1400         @Override
1401         public void write(byte b[], int off, int len)
1402                 throws IOException {
1403             out.write(b, off, len);
1404             crc.update(b, off, len);
1405             written += len;
1406         }
1407 
1408         @Override
1409         public void close() throws IOException {
1410             if (isClosed)
1411                 return;
1412             isClosed = true;
1413             e.size = e.csize = written;
1414             e.crc = crc.getValue();
1415         }
1416     }
1417 
1418     // Wrapper output stream class to write out a "deflated" entry.
1419     // (1) this class does not close the underlying out stream when
1420     //     being closed.
1421     // (2) no need to be "synchronized", only used by sync()
1422     private class EntryOutputStreamDef extends DeflaterOutputStream {
1423         private CRC32 crc;
1424         private Entry e;
1425         private boolean isClosed;
1426 
1427         EntryOutputStreamDef(Entry e, OutputStream os) throws IOException {
1428             super(os, getDeflater());
1429             this.e =  Objects.requireNonNull(e, "Zip entry is null");
1430             this.crc = new CRC32();
1431         }
1432 
1433         @Override
1434         public void write(byte b[], int off, int len)