@@ -914,6 +914,7 @@ SeekableByteChannel newByteChannel(byte[] path,
checkWritable ();
beginRead (); // only need a read lock, the "update()" will obtain
// the write lock when the channel is closed
ensureOpen ();
try {
Entry e = getEntry (path );
if (e != null ) {
@@ -1075,7 +1076,7 @@ public long read(ByteBuffer[] dsts, int offset, int length)
}
public int write (ByteBuffer src , long position )
throws IOException
{
{
return fch .write (src , position );
}
public MappedByteBuffer map (MapMode mode ,
@@ -1114,10 +1115,6 @@ protected void implCloseChannel() throws IOException {
private Set <InputStream > streams =
Collections .synchronizedSet (new HashSet <>());
// the ex-channel and ex-path that need to close when their outstanding
// input streams are all closed by the obtainers.
private final Set <ExistingChannelCloser > exChClosers = new HashSet <>();
private final Set <Path > tmppaths = Collections .synchronizedSet (new HashSet <>());
private Path getTempPathForEntry (byte [] path ) throws IOException {
Path tmpPath = createTempFileInSameDirectoryAs (zfpath );
@@ -1711,14 +1708,6 @@ private void writeTo(Entry e, OutputStream os) throws IOException {
// sync the zip file system, if there is any update
private void sync () throws IOException {
// check ex-closer
if (!exChClosers .isEmpty ()) {
for (ExistingChannelCloser ecc : exChClosers ) {
if (ecc .closeAndDeleteIfDone ()) {
exChClosers .remove (ecc );
}
}
}
if (!hasUpdate )
return ;
PosixFileAttributes attrs = getPosixAttributes (zfpath );
@@ -1781,22 +1770,8 @@ private void sync() throws IOException {
end .cenlen = written - end .cenoff ;
end .write (os , written , forceEnd64 );
}
if (!streams .isEmpty ()) {
//
// There are outstanding input streams open on existing "ch",
// so, don't close the "cha" and delete the "file for now, let
// the "ex-channel-closer" to handle them
Path path = createTempFileInSameDirectoryAs (zfpath );
ExistingChannelCloser ecc = new ExistingChannelCloser (path ,
ch ,
streams );
Files .move (zfpath , path , REPLACE_EXISTING );
exChClosers .add (ecc );
streams = Collections .synchronizedSet (new HashSet <>());
} else {
ch .close ();
Files .delete (zfpath );
}
ch .close ();
Files .delete (zfpath );
// Set the POSIX permissions of the original Zip File if available
// before moving the temp file
@@ -3141,36 +3116,6 @@ public Set<PosixFilePermission> permissions() {
}
}
private static class ExistingChannelCloser {
private final Path path ;
private final SeekableByteChannel ch ;
private final Set <InputStream > streams ;
ExistingChannelCloser (Path path ,
SeekableByteChannel ch ,
Set <InputStream > streams ) {
this .path = path ;
this .ch = ch ;
this .streams = streams ;
}
/**
* If there are no more outstanding streams, close the channel and
* delete the backing file
*
* @return true if we're done and closed the backing file,
* otherwise false
* @throws IOException
*/
private boolean closeAndDeleteIfDone () throws IOException {
if (streams .isEmpty ()) {
ch .close ();
Files .delete (path );
return true ;
}
return false ;
}
}
// purely for parent lookup, so we don't have to copy the parent
// name every time
static class ParentLookup extends IndexNode {