United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-7157656 : (zipfs) SeekableByteChannel to entry in zip file always reports its position as 0

Details
Type:
Bug
Submit Date:
2012-03-29
Status:
Closed
Updated Date:
2013-05-18
Project Name:
JDK
Resolved Date:
2012-05-27
Component:
core-libs
OS:
windows_7
Sub-Component:
java.nio
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:

Related Reports
Backport:

Sub Tasks

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/
                                     
2012-04-24
EVALUATION

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



Hardware and Software, Engineered to Work Together