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

Print this page




 486             }
 487             if (!hasCopyAttrs)
 488                 u.mtime = u.atime= u.ctime = System.currentTimeMillis();
 489             update(u);
 490             if (deletesrc)
 491                 updateDelete(eSrc);
 492         } finally {
 493             endWrite();
 494         }
 495     }
 496 
 497     // Returns an output stream for writing the contents into the specified
 498     // entry.
 499     OutputStream newOutputStream(byte[] path, OpenOption... options)
 500         throws IOException
 501     {
 502         checkWritable();
 503         boolean hasCreateNew = false;
 504         boolean hasCreate = false;
 505         boolean hasAppend = false;

 506         for (OpenOption opt: options) {
 507             if (opt == READ)
 508                 throw new IllegalArgumentException("READ not allowed");
 509             if (opt == CREATE_NEW)
 510                 hasCreateNew = true;
 511             if (opt == CREATE)
 512                 hasCreate = true;
 513             if (opt == APPEND)
 514                 hasAppend = true;


 515         }


 516         beginRead();                 // only need a readlock, the "update()" will
 517         try {                        // try to obtain a writelock when the os is
 518             ensureOpen();            // being closed.
 519             Entry e = getEntry0(path);
 520             if (e != null) {
 521                 if (e.isDir() || hasCreateNew)
 522                     throw new FileAlreadyExistsException(getString(path));
 523                 if (hasAppend) {
 524                     InputStream is = getInputStream(e);
 525                     OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
 526                     copyStream(is, os);
 527                     is.close();
 528                     return os;
 529                 }
 530                 return getOutputStream(new Entry(e, Entry.NEW));
 531             } else {
 532                 if (!hasCreate && !hasCreateNew)
 533                     throw new NoSuchFileException(getString(path));
 534                 checkParents(path);
 535                 return getOutputStream(new Entry(path, Entry.NEW));


 547             ensureOpen();
 548             Entry e = getEntry0(path);
 549             if (e == null)
 550                 throw new NoSuchFileException(getString(path));
 551             if (e.isDir())
 552                 throw new FileSystemException(getString(path), "is a directory", null);
 553             return getInputStream(e);
 554         } finally {
 555             endRead();
 556         }
 557     }
 558 
 559     private void checkOptions(Set<? extends OpenOption> options) {
 560         // check for options of null type and option is an intance of StandardOpenOption
 561         for (OpenOption option : options) {
 562             if (option == null)
 563                 throw new NullPointerException();
 564             if (!(option instanceof StandardOpenOption))
 565                 throw new IllegalArgumentException();
 566         }


 567     }
 568 
 569     // Returns a Writable/ReadByteChannel for now. Might consdier to use
 570     // newFileChannel() instead, which dump the entry data into a regular
 571     // file on the default file system and create a FileChannel on top of
 572     // it.
 573     SeekableByteChannel newByteChannel(byte[] path,
 574                                        Set<? extends OpenOption> options,
 575                                        FileAttribute<?>... attrs)
 576         throws IOException
 577     {
 578         checkOptions(options);
 579         if (options.contains(StandardOpenOption.WRITE) ||
 580             options.contains(StandardOpenOption.APPEND)) {
 581             checkWritable();
 582             beginRead();
 583             try {
 584                 final WritableByteChannel wbc = Channels.newChannel(
 585                     newOutputStream(path, options.toArray(new OpenOption[0])));
 586                 long leftover = 0;


 694     // Returns a FileChannel of the specified entry.
 695     //
 696     // This implementation creates a temporary file on the default file system,
 697     // copy the entry data into it if the entry exists, and then create a
 698     // FileChannel on top of it.
 699     FileChannel newFileChannel(byte[] path,
 700                                Set<? extends OpenOption> options,
 701                                FileAttribute<?>... attrs)
 702         throws IOException
 703     {
 704         checkOptions(options);
 705         final  boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
 706                                    options.contains(StandardOpenOption.APPEND));
 707         beginRead();
 708         try {
 709             ensureOpen();
 710             Entry e = getEntry0(path);
 711             if (forWrite) {
 712                 checkWritable();
 713                 if (e == null) {
 714                 if (!options.contains(StandardOpenOption.CREATE_NEW))

 715                     throw new NoSuchFileException(getString(path));

 716                 } else {
 717                     if (options.contains(StandardOpenOption.CREATE_NEW))
 718                         throw new FileAlreadyExistsException(getString(path));

 719                     if (e.isDir())
 720                         throw new FileAlreadyExistsException("directory <"
 721                             + getString(path) + "> exists");
 722                 }

 723                 options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
 724             } else if (e == null || e.isDir()) {
 725                 throw new NoSuchFileException(getString(path));
 726             }
 727 
 728             final boolean isFCH = (e != null && e.type == Entry.FILECH);
 729             final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
 730             final FileChannel fch = tmpfile.getFileSystem()
 731                                            .provider()
 732                                            .newFileChannel(tmpfile, options, attrs);
 733             final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
 734             if (forWrite) {
 735                 u.flag = FLAG_DATADESCR;
 736                 u.method = METHOD_DEFLATED;
 737             }
 738             // is there a better way to hook into the FileChannel's close method?
 739             return new FileChannel() {
 740                 public int write(ByteBuffer src) throws IOException {
 741                     return fch.write(src);
 742                 }




 486             }
 487             if (!hasCopyAttrs)
 488                 u.mtime = u.atime= u.ctime = System.currentTimeMillis();
 489             update(u);
 490             if (deletesrc)
 491                 updateDelete(eSrc);
 492         } finally {
 493             endWrite();
 494         }
 495     }
 496 
 497     // Returns an output stream for writing the contents into the specified
 498     // entry.
 499     OutputStream newOutputStream(byte[] path, OpenOption... options)
 500         throws IOException
 501     {
 502         checkWritable();
 503         boolean hasCreateNew = false;
 504         boolean hasCreate = false;
 505         boolean hasAppend = false;
 506         boolean hasTruncate = false;
 507         for (OpenOption opt: options) {
 508             if (opt == READ)
 509                 throw new IllegalArgumentException("READ not allowed");
 510             if (opt == CREATE_NEW)
 511                 hasCreateNew = true;
 512             if (opt == CREATE)
 513                 hasCreate = true;
 514             if (opt == APPEND)
 515                 hasAppend = true;
 516             if (opt == TRUNCATE_EXISTING)
 517                 hasTruncate = true;
 518         }
 519         if (hasAppend && hasTruncate)
 520             throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
 521         beginRead();                 // only need a readlock, the "update()" will
 522         try {                        // try to obtain a writelock when the os is
 523             ensureOpen();            // being closed.
 524             Entry e = getEntry0(path);
 525             if (e != null) {
 526                 if (e.isDir() || hasCreateNew)
 527                     throw new FileAlreadyExistsException(getString(path));
 528                 if (hasAppend) {
 529                     InputStream is = getInputStream(e);
 530                     OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
 531                     copyStream(is, os);
 532                     is.close();
 533                     return os;
 534                 }
 535                 return getOutputStream(new Entry(e, Entry.NEW));
 536             } else {
 537                 if (!hasCreate && !hasCreateNew)
 538                     throw new NoSuchFileException(getString(path));
 539                 checkParents(path);
 540                 return getOutputStream(new Entry(path, Entry.NEW));


 552             ensureOpen();
 553             Entry e = getEntry0(path);
 554             if (e == null)
 555                 throw new NoSuchFileException(getString(path));
 556             if (e.isDir())
 557                 throw new FileSystemException(getString(path), "is a directory", null);
 558             return getInputStream(e);
 559         } finally {
 560             endRead();
 561         }
 562     }
 563 
 564     private void checkOptions(Set<? extends OpenOption> options) {
 565         // check for options of null type and option is an intance of StandardOpenOption
 566         for (OpenOption option : options) {
 567             if (option == null)
 568                 throw new NullPointerException();
 569             if (!(option instanceof StandardOpenOption))
 570                 throw new IllegalArgumentException();
 571         }
 572         if (options.contains(APPEND) && options.contains(TRUNCATE_EXISTING))
 573             throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
 574     }
 575 
 576     // Returns a Writable/ReadByteChannel for now. Might consdier to use
 577     // newFileChannel() instead, which dump the entry data into a regular
 578     // file on the default file system and create a FileChannel on top of
 579     // it.
 580     SeekableByteChannel newByteChannel(byte[] path,
 581                                        Set<? extends OpenOption> options,
 582                                        FileAttribute<?>... attrs)
 583         throws IOException
 584     {
 585         checkOptions(options);
 586         if (options.contains(StandardOpenOption.WRITE) ||
 587             options.contains(StandardOpenOption.APPEND)) {
 588             checkWritable();
 589             beginRead();
 590             try {
 591                 final WritableByteChannel wbc = Channels.newChannel(
 592                     newOutputStream(path, options.toArray(new OpenOption[0])));
 593                 long leftover = 0;


 701     // Returns a FileChannel of the specified entry.
 702     //
 703     // This implementation creates a temporary file on the default file system,
 704     // copy the entry data into it if the entry exists, and then create a
 705     // FileChannel on top of it.
 706     FileChannel newFileChannel(byte[] path,
 707                                Set<? extends OpenOption> options,
 708                                FileAttribute<?>... attrs)
 709         throws IOException
 710     {
 711         checkOptions(options);
 712         final  boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
 713                                    options.contains(StandardOpenOption.APPEND));
 714         beginRead();
 715         try {
 716             ensureOpen();
 717             Entry e = getEntry0(path);
 718             if (forWrite) {
 719                 checkWritable();
 720                 if (e == null) {
 721                     if (!options.contains(StandardOpenOption.CREATE) &&
 722                         !options.contains(StandardOpenOption.CREATE_NEW)) {
 723                         throw new NoSuchFileException(getString(path));
 724                     }
 725                 } else {
 726                     if (options.contains(StandardOpenOption.CREATE_NEW)) {
 727                         throw new FileAlreadyExistsException(getString(path));
 728                     }
 729                     if (e.isDir())
 730                         throw new FileAlreadyExistsException("directory <"
 731                             + getString(path) + "> exists");
 732                 }
 733                 options = new HashSet<>(options);
 734                 options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
 735             } else if (e == null || e.isDir()) {
 736                 throw new NoSuchFileException(getString(path));
 737             }
 738 
 739             final boolean isFCH = (e != null && e.type == Entry.FILECH);
 740             final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
 741             final FileChannel fch = tmpfile.getFileSystem()
 742                                            .provider()
 743                                            .newFileChannel(tmpfile, options, attrs);
 744             final Entry u = isFCH ? e : new Entry(path, tmpfile, Entry.FILECH);
 745             if (forWrite) {
 746                 u.flag = FLAG_DATADESCR;
 747                 u.method = METHOD_DEFLATED;
 748             }
 749             // is there a better way to hook into the FileChannel's close method?
 750             return new FileChannel() {
 751                 public int write(ByteBuffer src) throws IOException {
 752                     return fch.write(src);
 753                 }