6526860: (fc) FileChannel.position returns 0 when FileOutputStream opened in append mode
authoralanb
Thu, 17 Feb 2011 20:50:22 +0000
changeset 8402 41789c995fe2
parent 8398 ffe782989540
child 8403 dfb0ceced38b
6526860: (fc) FileChannel.position returns 0 when FileOutputStream opened in append mode Reviewed-by: forax
jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java
jdk/test/java/nio/channels/FileChannel/Position.java
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Feb 16 12:38:13 2011 +0000
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java	Thu Feb 17 20:50:22 2011 +0000
@@ -51,6 +51,7 @@
     // File access mode (immutable)
     private final boolean writable;
     private final boolean readable;
+    private final boolean append;
 
     // Required to prevent finalization of creating stream (immutable)
     private final Object parent;
@@ -67,6 +68,7 @@
         this.fd = fd;
         this.readable = readable;
         this.writable = writable;
+        this.append = append;
         this.parent = parent;
         this.nd = new FileDispatcherImpl(append);
     }
@@ -242,7 +244,8 @@
                 if (!isOpen())
                     return 0;
                 do {
-                    p = position0(fd, -1);
+                    // in append-mode then position is advanced to end before writing
+                    p = (append) ? nd.size(fd) : position0(fd, -1);
                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
                 return IOStatus.normalize(p);
             } finally {
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java	Wed Feb 16 12:38:13 2011 +0000
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java	Thu Feb 17 20:50:22 2011 +0000
@@ -136,7 +136,7 @@
             throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
 
         FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode);
-        return FileChannelImpl.open(fdObj, flags.read, flags.write, null);
+        return FileChannelImpl.open(fdObj, flags.read, flags.write, flags.append, null);
     }
 
     /**
--- a/jdk/test/java/nio/channels/FileChannel/Position.java	Wed Feb 16 12:38:13 2011 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/Position.java	Thu Feb 17 20:50:22 2011 +0000
@@ -22,13 +22,16 @@
  */
 
 /* @test
+ * @bug 4429043 6526860
  * @summary Test position method of FileChannel
  */
 
 import java.io.*;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.*;
+import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
+import java.nio.file.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.charset.Charset;
 import java.util.Random;
 
 
@@ -38,32 +41,42 @@
 
 public class Position {
 
-    private static PrintStream err = System.err;
-
-    private static Random generator = new Random();
+    private static final Charset ISO8859_1 = Charset.forName("8859_1");
 
-    private static int CHARS_PER_LINE = File.separatorChar == '/' ? 5 : 6;
-
-    private static File blah;
+    private static final Random generator = new Random();
 
     public static void main(String[] args) throws Exception {
-        blah = File.createTempFile("blah", null);
-        blah.deleteOnExit();
+        Path blah = Files.createTempFile("blah", null);
+        blah.toFile().deleteOnExit();
         initTestFile(blah);
 
-        FileInputStream fis = new FileInputStream(blah);
-        FileChannel c = fis.getChannel();
-
-        for(int i=0; i<100; i++) {
-            long newPos = generator.nextInt(1000);
-            c.position(newPos);
-            if (c.position() != newPos)
-                throw new RuntimeException("Position failed");
+        for (int i=0; i<10; i++) {
+            try (FileChannel fc = (generator.nextBoolean()) ?
+                    FileChannel.open(blah, READ) :
+                    new FileInputStream(blah.toFile()).getChannel()) {
+                for (int j=0; j<100; j++) {
+                    long newPos = generator.nextInt(1000);
+                    fc.position(newPos);
+                    if (fc.position() != newPos)
+                        throw new RuntimeException("Position failed");
+                }
+            }
         }
 
-        c.close();
-        fis.close();
-        blah.delete();
+        for (int i=0; i<10; i++) {
+            try (FileChannel fc = (generator.nextBoolean()) ?
+                     FileChannel.open(blah, APPEND) :
+                     new FileOutputStream(blah.toFile(), true).getChannel()) {
+                for (int j=0; j<10; j++) {
+                    if (fc.position() != fc.size())
+                        throw new RuntimeException("Position expected to be size");
+                    byte[] buf = new byte[generator.nextInt(100)];
+                    fc.write(ByteBuffer.wrap(buf));
+                }
+            }
+        }
+
+        Files.delete(blah);
     }
 
     /**
@@ -78,19 +91,15 @@
      * 3999
      *
      */
-    private static void initTestFile(File blah) throws Exception {
-        FileOutputStream fos = new FileOutputStream(blah);
-        BufferedWriter awriter
-            = new BufferedWriter(new OutputStreamWriter(fos, "8859_1"));
-
-        for(int i=0; i<4000; i++) {
-            String number = new Integer(i).toString();
-            for (int h=0; h<4-number.length(); h++)
-                awriter.write("0");
-            awriter.write(""+i);
-            awriter.newLine();
+    private static void initTestFile(Path blah) throws IOException {
+        try (BufferedWriter awriter = Files.newBufferedWriter(blah, ISO8859_1)) {
+            for(int i=0; i<4000; i++) {
+                String number = new Integer(i).toString();
+                for (int h=0; h<4-number.length(); h++)
+                    awriter.write("0");
+                awriter.write(""+i);
+                awriter.newLine();
+            }
         }
-       awriter.flush();
-       awriter.close();
     }
 }