JDK-7157656 : (zipfs) SeekableByteChannel to entry in zip file always reports its position as 0
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_7
  • CPU: x86
  • Submitted: 2012-03-29
  • Updated: 2013-06-26
  • Resolved: 2012-05-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u40Fixed 8 b40Fixed
Description
FULL PRODUCT VERSION :
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
The method channel.position() of ZipFileSystem channels (created with Files.newByteChannel(..) ) return 0 always. Instead they should return the number of unzipped bytes read.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
The testcase attached shows the problem.

1. Open a zip file using the FileSystems.newFileSystem(..) method
2. Create a SeekableByteChannel for a file contained in the zip file using the method Files.newByteChannel(file, StandardOpenOption.READ)
3. Read some bytes from the channel
4. Check the result of channel.position().
=> The result is always 0



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The test program should output

channel.position() after 10 bytes read: 10
ACTUAL -
The test program output is

channel.position() after 10 bytes read: 0

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

public class ZipFileSystemRead
{

    public static void main(String[] args)
        throws IOException
    {
        // create the zip file
        URI uri = URI.create("jar:file:/zipfstest.zip");
        Map<String, String> env = new HashMap<>();
        env.put("create", "true");
        try (FileSystem zipfs = FileSystems.newFileSystem(uri, env, null))
        {
            Path file = zipfs.getPath("test.dat");
            try (
                 OutputStream out = Files.newOutputStream(file, StandardOpenOption.CREATE,
                     StandardOpenOption.WRITE))
            {
                // fill the file with random data
                for (int c = 0; c < 1000; c++)
                {
                    out.write(ThreadLocalRandom.current().nextInt());
                }
            }
        }

        // open the zip file and read from it
        try (
             FileSystem zipfs = FileSystems.newFileSystem(uri,
                 Collections.<String, String> emptyMap(), null))
        {
            Path file = zipfs.getPath("test.dat");
            try (SeekableByteChannel channel = Files.newByteChannel(file, StandardOpenOption.READ))
            {
                ByteBuffer buf = ByteBuffer.allocate(10);
                channel.read(buf);
                System.out.println("channel.position() after 10 bytes read: " + channel.position());
            }
        }
    }
}
---------- END SOURCE ----------

Comments
SUGGESTED FIX Patch is here: http://cr.openjdk.java.net/~psandoz/7157656/webrev.0/
24-04-2012

EVALUATION There is an overlook in the implementation of SeekableByteChannel.read() method. The byte read counter is not being updated appropritely.
03-04-2012