# HG changeset patch
# User alanb
# Date 1381520835 -3600
# Node ID 483371f41926b9a67a52a9134fc8a228faaf007a
# Parent 26af21e74a8db09a6c67ba49f372aa682367ce08
8019526: (fs) Files.lines, etc without Charset parameter
Reviewed-by: psandoz, henryjen
diff -r 26af21e74a8d -r 483371f41926 jdk/src/share/classes/java/nio/file/Files.java
--- a/jdk/src/share/classes/java/nio/file/Files.java Fri Oct 11 20:47:16 2013 +0100
+++ b/jdk/src/share/classes/java/nio/file/Files.java Fri Oct 11 20:47:15 2013 +0100
@@ -43,9 +43,10 @@
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.DosFileAttributes;
+import java.nio.file.attribute.DosFileAttributes; // javadoc
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileOwnerAttributeView;
@@ -104,8 +105,7 @@
return () -> {
try {
c.close();
- }
- catch (IOException e) {
+ } catch (IOException e) {
throw new UncheckedIOException(e);
}
};
@@ -2550,7 +2550,7 @@
* checkExec} is invoked to check execute access to the file.
*/
public static boolean isExecutable(Path path) {
- return isAccessible(path, AccessMode.EXECUTE);
+ return isAccessible(path, AccessMode.EXECUTE);
}
// -- Recursive operations --
@@ -2783,6 +2783,37 @@
}
/**
+ * Opens a file for reading, returning a {@code BufferedReader} to read text
+ * from the file in an efficient manner. Bytes from the file are decoded into
+ * characters using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset
+ * charset}.
+ *
+ *
This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ *
{@code
+ * Files.newBufferedReader(path, StandardCharsets.UTF_8)
+ * }
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return a new buffered reader, with default buffer size, to read text
+ * from the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @since 1.8
+ */
+ public static BufferedReader newBufferedReader(Path path) throws IOException {
+ return newBufferedReader(path, StandardCharsets.UTF_8);
+ }
+
+ /**
* Opens or creates a file for writing, returning a {@code BufferedWriter}
* that may be used to write text to the file in an efficient manner.
* The {@code options} parameter specifies how the the file is created or
@@ -2828,6 +2859,41 @@
}
/**
+ * Opens or creates a file for writing, returning a {@code BufferedWriter}
+ * to write text to the file in an efficient manner. The text is encoded
+ * into bytes for writing using the {@link StandardCharsets#UTF_8 UTF-8}
+ * {@link Charset charset}.
+ *
+ * This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ *
{@code
+ * Files.newBufferedWriter(path, StandardCharsets.UTF_8, options)
+ * }
+ *
+ * @param path
+ * the path to the file
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return a new buffered writer, with default buffer size, to write text
+ * to the file
+ *
+ * @throws IOException
+ * if an I/O error occurs opening or creating the file
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ *
+ * @since 1.8
+ */
+ public static BufferedWriter newBufferedWriter(Path path, OpenOption... options) throws IOException {
+ return newBufferedWriter(path, StandardCharsets.UTF_8, options);
+ }
+
+ /**
* Reads all bytes from an input stream and writes them to an output stream.
*/
private static long copy(InputStream source, OutputStream sink)
@@ -3025,9 +3091,7 @@
* @throws OutOfMemoryError
* if an array of the required size cannot be allocated
*/
- private static byte[] read(InputStream source, int initialSize)
- throws IOException
- {
+ private static byte[] read(InputStream source, int initialSize) throws IOException {
int capacity = initialSize;
byte[] buf = new byte[capacity];
int nread = 0;
@@ -3131,9 +3195,7 @@
*
* @see #newBufferedReader
*/
- public static List readAllLines(Path path, Charset cs)
- throws IOException
- {
+ public static List readAllLines(Path path, Charset cs) throws IOException {
try (BufferedReader reader = newBufferedReader(path, cs)) {
List result = new ArrayList<>();
for (;;) {
@@ -3147,6 +3209,37 @@
}
/**
+ * Read all lines from a file. Bytes from the file are decoded into characters
+ * using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
+ *
+ * This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ *
{@code
+ * Files.readAllLines(path, StandardCharsets.UTF_8)
+ * }
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the lines from the file as a {@code List}; whether the {@code
+ * List} is modifiable or not is implementation dependent and
+ * therefore not specified
+ *
+ * @throws IOException
+ * if an I/O error occurs reading from the file or a malformed or
+ * unmappable byte sequence is read
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @since 1.8
+ */
+ public static List readAllLines(Path path) throws IOException {
+ return readAllLines(path, StandardCharsets.UTF_8);
+ }
+
+ /**
* Writes bytes to a file. The {@code options} parameter specifies how the
* the file is created or opened. If no options are present then this method
* works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
@@ -3262,6 +3355,45 @@
return path;
}
+ /**
+ * Write lines of text to a file. Characters are encoded into bytes using
+ * the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
+ *
+ * This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ *
{@code
+ * Files.write(path, lines, StandardCharsets.UTF_8, options);
+ * }
+ *
+ * @param path
+ * the path to the file
+ * @param lines
+ * an object to iterate over the char sequences
+ * @param options
+ * options specifying how the file is opened
+ *
+ * @return the path
+ *
+ * @throws IOException
+ * if an I/O error occurs writing to or creating the file, or the
+ * text cannot be encoded as {@code UTF-8}
+ * @throws UnsupportedOperationException
+ * if an unsupported option is specified
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+ * method is invoked to check write access to the file.
+ *
+ * @since 1.8
+ */
+ public static Path write(Path path,
+ Iterable extends CharSequence> lines,
+ OpenOption... options)
+ throws IOException
+ {
+ return write(path, lines, StandardCharsets.UTF_8, options);
+ }
+
// -- Stream APIs --
/**
@@ -3431,9 +3563,11 @@
* if an I/O error is thrown when accessing the starting file.
* @since 1.8
*/
- public static Stream walk(Path start, int maxDepth,
+ public static Stream walk(Path start,
+ int maxDepth,
FileVisitOption... options)
- throws IOException {
+ throws IOException
+ {
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
try {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
@@ -3484,9 +3618,7 @@
* @see #walk(Path, int, FileVisitOption...)
* @since 1.8
*/
- public static Stream walk(Path start,
- FileVisitOption... options)
- throws IOException {
+ public static Stream walk(Path start, FileVisitOption... options) throws IOException {
return walk(start, Integer.MAX_VALUE, options);
}
@@ -3547,7 +3679,8 @@
int maxDepth,
BiPredicate matcher,
FileVisitOption... options)
- throws IOException {
+ throws IOException
+ {
FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
try {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
@@ -3561,7 +3694,7 @@
}
/**
- * Read all lines from a file as a {@code Stream}. Unlike {@link
+ * Read all lines from a file as a {@code Stream}. Unlike {@link
* #readAllLines(Path, Charset) readAllLines}, this method does not read
* all lines into a {@code List}, but instead populates lazily as the stream
* is consumed.
@@ -3619,4 +3752,33 @@
throw e;
}
}
+
+ /**
+ * Read all lines from a file as a {@code Stream}. Bytes from the file are
+ * decoded into characters using the {@link StandardCharsets#UTF_8 UTF-8}
+ * {@link Charset charset}.
+ *
+ * This method works as if invoking it were equivalent to evaluating the
+ * expression:
+ *
{@code
+ * Files.lines(path, StandardCharsets.UTF_8)
+ * }
+ *
+ * @param path
+ * the path to the file
+ *
+ * @return the lines from the file as a {@code Stream}
+ *
+ * @throws IOException
+ * if an I/O error occurs opening the file
+ * @throws SecurityException
+ * In the case of the default provider, and a security manager is
+ * installed, the {@link SecurityManager#checkRead(String) checkRead}
+ * method is invoked to check read access to the file.
+ *
+ * @since 1.8
+ */
+ public static Stream lines(Path path) throws IOException {
+ return lines(path, StandardCharsets.UTF_8);
+ }
}
diff -r 26af21e74a8d -r 483371f41926 jdk/test/java/nio/file/Files/BytesAndLines.java
--- a/jdk/test/java/nio/file/Files/BytesAndLines.java Fri Oct 11 20:47:16 2013 +0100
+++ b/jdk/test/java/nio/file/Files/BytesAndLines.java Fri Oct 11 20:47:15 2013 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,262 +22,318 @@
*/
/* @test
- * @bug 7006126 8020669 8024788
+ * @bug 7006126 8020669 8024788 8019526
* @build BytesAndLines PassThroughFileSystem
- * @run main BytesAndLines
+ * @run testng BytesAndLines
* @summary Unit test for methods for Files readAllBytes, readAllLines and
* and write methods.
*/
-import java.nio.file.*;
-import static java.nio.file.Files.*;
-import java.io.*;
-import java.util.*;
-import java.nio.charset.*;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.OpenOption;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.charset.Charset;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
+import static java.nio.charset.StandardCharsets.*;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.io.IOException;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test(groups = "unit")
public class BytesAndLines {
- static final Random rand = new Random();
+
+ // data for text files
+ private static final String EN_STRING = "The quick brown fox jumps over the lazy dog";
+ private static final String JA_STRING = "\u65e5\u672c\u8a9e\u6587\u5b57\u5217";
- static final Charset US_ASCII = Charset.forName("US-ASCII");
+ // used for random byte content
+ private static Random RAND = new Random();
+
+ // file used by most tests
+ private Path tmpfile;
- public static void main(String[] args) throws IOException {
- testReadAndWriteBytes();
- testReadLines();
- testWriteLines();
+ @BeforeClass
+ void setup() throws IOException {
+ tmpfile = Files.createTempFile("blah", null);
+ }
+
+ @AfterClass
+ void cleanup() throws IOException {
+ Files.deleteIfExists(tmpfile);
+ }
+
+ /**
+ * Returns a byte[] of the given size with random content
+ */
+ private byte[] genBytes(int size) {
+ byte[] arr = new byte[size];
+ RAND.nextBytes(arr);
+ return arr;
}
/**
- * Test readAllBytes(Path) and write(Path, byte[], OpenOption...)
+ * Exercise NullPointerException
*/
- static void testReadAndWriteBytes() throws IOException {
- // exercise methods with various sizes
- testReadAndWriteBytes(0);
- for (int i=0; i<100; i++) {
- testReadAndWriteBytes(rand.nextInt(32000));
- }
-
- // NullPointerException
+ public void testNulls() {
Path file = Paths.get("foo");
+ byte[] bytes = new byte[100];
List lines = Collections.emptyList();
- try {
- readAllBytes(null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- write(null, lines, Charset.defaultCharset());
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- write(file, null, Charset.defaultCharset());
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
+
+ checkNullPointerException(() -> Files.readAllBytes(null));
+
+ checkNullPointerException(() -> Files.write(null, bytes));
+ checkNullPointerException(() -> Files.write(file, (byte[])null));
+ checkNullPointerException(() -> Files.write(file, bytes, (OpenOption[])null));
+ checkNullPointerException(() -> Files.write(file, bytes, new OpenOption[] { null } ));
+
+ checkNullPointerException(() -> Files.readAllLines(null));
+ checkNullPointerException(() -> Files.readAllLines(file, (Charset)null));
+ checkNullPointerException(() -> Files.readAllLines(null, Charset.defaultCharset()));
+
+ checkNullPointerException(() -> Files.write(null, lines));
+ checkNullPointerException(() -> Files.write(file, (List)null));
+ checkNullPointerException(() -> Files.write(file, lines, (OpenOption[])null));
+ checkNullPointerException(() -> Files.write(file, lines, new OpenOption[] { null } ));
+ checkNullPointerException(() -> Files.write(null, lines, Charset.defaultCharset()));
+ checkNullPointerException(() -> Files.write(file, null, Charset.defaultCharset()));
+ checkNullPointerException(() -> Files.write(file, lines, (Charset)null));
+ checkNullPointerException(() -> Files.write(file, lines, Charset.defaultCharset(), (OpenOption[])null));
+ checkNullPointerException(() -> Files.write(file, lines, Charset.defaultCharset(), new OpenOption[] { null } ));
+ }
+
+ private void checkNullPointerException(Callable> c) {
try {
- write(file, lines, null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- write(file, lines, Charset.defaultCharset(), (OpenOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- OpenOption[] opts = { null };
- write(file, lines, Charset.defaultCharset(), opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
-
- // read from procfs
- if (System.getProperty("os.name").equals("Linux")) {
- // Refer to the Linux proc(5) man page for details about /proc/self/stat file
- // procfs reports it to be zero sized, even though data can be read from it
- String statFile = "/proc/self/stat";
- Path pathStat = Paths.get(statFile);
- byte[] data = Files.readAllBytes(pathStat);
- assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read");
- }
-
- // test readAllBytes on custom file system
- Path myfile = PassThroughFileSystem.create().getPath(file.toString());
- for (int size=0; size<=1024; size+=512) {
- byte[] b1 = new byte[size];
- rand.nextBytes(b1);
- Files.write(myfile, b1);
- byte[] b2 = Files.readAllBytes(myfile);
- assertTrue(Arrays.equals(b1, b2), "bytes not equal");
+ c.call();
+ fail("NullPointerException expected");
+ } catch (NullPointerException ignore) {
+ } catch (Exception e) {
+ fail(e + " not expected");
}
}
-
- static void testReadAndWriteBytes(int size) throws IOException {
- Path path = createTempFile("blah", null);
- try {
- boolean append = rand.nextBoolean();
-
- byte[] b1 = new byte[size];
- rand.nextBytes(b1);
+ /**
+ * Exercise Files.readAllBytes(Path) on varied file sizes
+ */
+ public void testReadAllBytes() throws IOException {
+ int size = 0;
+ while (size <= 16*1024) {
+ testReadAllBytes(size);
+ size += 512;
+ }
+ }
- byte[] b2 = (append) ? new byte[size] : new byte[0];
- rand.nextBytes(b2);
-
- // write method should create file if it doesn't exist
- if (rand.nextBoolean())
- delete(path);
-
- // write bytes to file
- Path target = write(path, b1);
- assertTrue(target==path, "Unexpected path");
- assertTrue(size(path) == b1.length, "Unexpected file size");
+ private void testReadAllBytes(int size) throws IOException {
+ // write bytes to file (random content)
+ byte[] expected = genBytes(size);
+ Files.write(tmpfile, expected);
- // append bytes to file (might be 0 bytes)
- write(path, b2, StandardOpenOption.APPEND);
- assertTrue(size(path) == b1.length + b2.length, "Unexpected file size");
-
- // read entire file
- byte[] read = readAllBytes(path);
+ // check expected bytes are read
+ byte[] read = Files.readAllBytes(tmpfile);
+ assertTrue(Arrays.equals(read, expected), "Bytes read not the same as written");
+ }
- // check bytes are correct
- byte[] expected;
- if (append) {
- expected = new byte[b1.length + b2.length];
- System.arraycopy(b1, 0, expected, 0, b1.length);
- System.arraycopy(b2, 0, expected, b1.length, b2.length);
- } else {
- expected = b1;
- }
- assertTrue(Arrays.equals(read, expected),
- "Bytes read not the same as bytes written");
- } finally {
- deleteIfExists(path);
+ /**
+ * Linux specific test to exercise Files.readAllBytes on /proc. This is
+ * special because file sizes are reported as 0 even though the file
+ * has content.
+ */
+ public void testReadAllBytesOnProcFS() throws IOException {
+ // read from procfs
+ if (System.getProperty("os.name").equals("Linux")) {
+ Path statFile = Paths.get("/proc/self/stat");
+ byte[] data = Files.readAllBytes(statFile);
+ assertTrue(data.length > 0, "Files.readAllBytes('" + statFile + "') failed to read");
}
}
/**
- * Test readAllLines(Path,Charset)
+ * Exercise Files.readAllBytes(Path) on custom file system. This is special
+ * because readAllBytes was originally implemented to use FileChannel
+ * and so may not be supported by custom file system providers.
*/
- static void testReadLines() throws IOException {
- Path tmpfile = createTempFile("blah", "txt");
+ public void testReadAllBytesOnCustomFS() throws IOException {
+ Path myfile = PassThroughFileSystem.create().getPath("myfile");
try {
- List lines;
-
- // zero lines
- assertTrue(size(tmpfile) == 0, "File should be empty");
- lines = readAllLines(tmpfile, US_ASCII);
- assertTrue(lines.isEmpty(), "No line expected");
-
- // one line
- byte[] hi = { (byte)'h', (byte)'i' };
- write(tmpfile, hi);
- lines = readAllLines(tmpfile, US_ASCII);
- assertTrue(lines.size() == 1, "One line expected");
- assertTrue(lines.get(0).equals("hi"), "'Hi' expected");
-
- // two lines using platform's line separator
- List expected = Arrays.asList("hi", "there");
- write(tmpfile, expected, US_ASCII);
- assertTrue(size(tmpfile) > 0, "File is empty");
- lines = readAllLines(tmpfile, US_ASCII);
- assertTrue(lines.equals(expected), "Unexpected lines");
-
- // MalformedInputException
- byte[] bad = { (byte)0xff, (byte)0xff };
- write(tmpfile, bad);
- try {
- readAllLines(tmpfile, US_ASCII);
- throw new RuntimeException("MalformedInputException expected");
- } catch (MalformedInputException ignore) { }
-
-
- // NullPointerException
- try {
- readAllLines(null, US_ASCII);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- readAllLines(tmpfile, null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
-
- // read from procfs
- if (System.getProperty("os.name").equals("Linux")) {
- // Refer to the Linux proc(5) man page for details about /proc/self/status file
- // procfs reports this file to be zero sized, even though data can be read from it
- String statusFile = "/proc/self/status";
- Path pathStatus = Paths.get(statusFile);
- lines = Files.readAllLines(pathStatus, US_ASCII);
- assertTrue(lines.size() > 0, "Files.readAllLines('" + pathStatus + "') failed to read");
+ int size = 0;
+ while (size <= 1024) {
+ byte[] b1 = genBytes(size);
+ Files.write(myfile, b1);
+ byte[] b2 = Files.readAllBytes(myfile);
+ assertTrue(Arrays.equals(b1, b2), "bytes not equal");
+ size += 512;
}
-
} finally {
- delete(tmpfile);
+ Files.deleteIfExists(myfile);
}
}
/**
- * Test write(Path,Iterable extends CharSequence>,Charset,OpenOption...)
+ * Exercise Files.write(Path, byte[], OpenOption...) on various sizes
*/
- static void testWriteLines() throws IOException {
- Path tmpfile = createTempFile("blah", "txt");
- try {
- // write method should create file if it doesn't exist
- if (rand.nextBoolean())
- delete(tmpfile);
-
- // zero lines
- Path result = write(tmpfile, Collections.emptyList(), US_ASCII);
- assert(size(tmpfile) == 0);
- assert(result == tmpfile);
-
- // two lines
- List lines = Arrays.asList("hi", "there");
- write(tmpfile, lines, US_ASCII);
- List actual = readAllLines(tmpfile, US_ASCII);
- assertTrue(actual.equals(lines), "Unexpected lines");
-
- // append two lines
- write(tmpfile, lines, US_ASCII, StandardOpenOption.APPEND);
- List expected = new ArrayList();
- expected.addAll(lines);
- expected.addAll(lines);
- assertTrue(expected.size() == 4, "List should have 4 elements");
- actual = readAllLines(tmpfile, US_ASCII);
- assertTrue(actual.equals(expected), "Unexpected lines");
-
- // UnmappableCharacterException
- try {
- String s = "\u00A0\u00A1";
- write(tmpfile, Arrays.asList(s), US_ASCII);
- throw new RuntimeException("UnmappableCharacterException expected");
- } catch (UnmappableCharacterException ignore) { }
-
- // NullPointerException
- try {
- write(null, lines, US_ASCII);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- write(tmpfile, null, US_ASCII);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- write(tmpfile, lines, null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- write(tmpfile, lines, US_ASCII, (OpenOption[])null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- OpenOption[] opts = { (OpenOption)null };
- write(tmpfile, lines, US_ASCII, opts);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
-
- } finally {
- delete(tmpfile);
+ public void testWriteBytes() throws IOException {
+ int size = 0;
+ while (size < 16*1024) {
+ testWriteBytes(size, false);
+ testWriteBytes(size, true);
+ size += 512;
}
}
- static void assertTrue(boolean expr, String errmsg) {
- if (!expr)
- throw new RuntimeException(errmsg);
+ private void testWriteBytes(int size, boolean append) throws IOException {
+ byte[] bytes = genBytes(size);
+ Path result = Files.write(tmpfile, bytes);
+ assertTrue(result == tmpfile);
+ if (append) {
+ Files.write(tmpfile, bytes, APPEND);
+ assertTrue(Files.size(tmpfile) == size*2);
+ }
+
+ byte[] expected;
+ if (append) {
+ expected = new byte[size << 1];
+ System.arraycopy(bytes, 0, expected, 0, bytes.length);
+ System.arraycopy(bytes, 0, expected, bytes.length, bytes.length);
+ } else {
+ expected = bytes;
+ }
+
+ byte[] read = Files.readAllBytes(tmpfile);
+ assertTrue(Arrays.equals(read, expected), "Bytes read not the same as written");
+ }
+
+ /**
+ * Exercise Files.readAllLines(Path, Charset)
+ */
+ public void testReadAllLines() throws IOException {
+ // zero lines
+ Files.write(tmpfile, new byte[0]);
+ List lines = Files.readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.isEmpty(), "No line expected");
+
+ // one line
+ byte[] hi = { (byte)'h', (byte)'i' };
+ Files.write(tmpfile, hi);
+ lines = Files.readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.size() == 1, "One line expected");
+ assertTrue(lines.get(0).equals("hi"), "'Hi' expected");
+
+ // two lines using platform's line separator
+ List expected = Arrays.asList("hi", "there");
+ Files.write(tmpfile, expected, US_ASCII);
+ assertTrue(Files.size(tmpfile) > 0, "File is empty");
+ lines = Files.readAllLines(tmpfile, US_ASCII);
+ assertTrue(lines.equals(expected), "Unexpected lines");
+
+ // MalformedInputException
+ byte[] bad = { (byte)0xff, (byte)0xff };
+ Files.write(tmpfile, bad);
+ try {
+ Files.readAllLines(tmpfile, US_ASCII);
+ fail("MalformedInputException expected");
+ } catch (MalformedInputException ignore) { }
+ }
+
+ /**
+ * Linux specific test to exercise Files.readAllLines(Path) on /proc. This
+ * is special because file sizes are reported as 0 even though the file
+ * has content.
+ */
+ public void testReadAllLinesOnProcFS() throws IOException {
+ if (System.getProperty("os.name").equals("Linux")) {
+ Path statFile = Paths.get("/proc/self/stat");
+ List lines = Files.readAllLines(statFile);
+ assertTrue(lines.size() > 0, "Files.readAllLines('" + statFile + "') failed to read");
+ }
+ }
+
+ /**
+ * Exercise Files.readAllLines(Path)
+ */
+ public void testReadAllLinesUTF8() throws IOException {
+ Files.write(tmpfile, encodeAsUTF8(EN_STRING + "\n" + JA_STRING));
+
+ List lines = Files.readAllLines(tmpfile);
+ assertTrue(lines.size() == 2, "Read " + lines.size() + " lines instead of 2");
+ assertTrue(lines.get(0).equals(EN_STRING));
+ assertTrue(lines.get(1).equals(JA_STRING));
+
+ // a sample of malformed sequences
+ testReadAllLinesMalformedUTF8((byte)0xFF); // one-byte sequence
+ testReadAllLinesMalformedUTF8((byte)0xC0, (byte)0x80); // invalid first byte
+ testReadAllLinesMalformedUTF8((byte)0xC2, (byte)0x00); // invalid second byte
+ }
+
+ private byte[] encodeAsUTF8(String s) throws CharacterCodingException {
+ // not using s.getBytes here so as to catch unmappable characters
+ ByteBuffer bb = UTF_8.newEncoder().encode(CharBuffer.wrap(s));
+ byte[] result = new byte[bb.limit()];
+ bb.get(result);
+ assertTrue(bb.remaining() == 0);
+ return result;
+ }
+
+ private void testReadAllLinesMalformedUTF8(byte... bytes) throws IOException {
+ Files.write(tmpfile, bytes);
+ try {
+ Files.readAllLines(tmpfile);
+ fail("MalformedInputException expected");
+ } catch (MalformedInputException ignore) { }
+ }
+
+ /**
+ * Exercise Files.write(Path, Iterable extends CharSequence>, Charset, OpenOption...)
+ */
+ public void testWriteLines() throws IOException {
+ // zero lines
+ Path result = Files.write(tmpfile, Collections.emptyList(), US_ASCII);
+ assert(Files.size(tmpfile) == 0);
+ assert(result == tmpfile);
+
+ // two lines
+ List lines = Arrays.asList("hi", "there");
+ Files.write(tmpfile, lines, US_ASCII);
+ List actual = Files.readAllLines(tmpfile, US_ASCII);
+ assertTrue(actual.equals(lines), "Unexpected lines");
+
+ // append two lines
+ Files.write(tmpfile, lines, US_ASCII, APPEND);
+ List expected = new ArrayList<>();
+ expected.addAll(lines);
+ expected.addAll(lines);
+ assertTrue(expected.size() == 4, "List should have 4 elements");
+ actual = Files.readAllLines(tmpfile, US_ASCII);
+ assertTrue(actual.equals(expected), "Unexpected lines");
+
+ // UnmappableCharacterException
+ try {
+ String s = "\u00A0\u00A1";
+ Files.write(tmpfile, Arrays.asList(s), US_ASCII);
+ fail("UnmappableCharacterException expected");
+ } catch (UnmappableCharacterException ignore) { }
+ }
+
+ /**
+ * Exercise Files.write(Path, Iterable extends CharSequence>, OpenOption...)
+ */
+ public void testWriteLinesUTF8() throws IOException {
+ List lines = Arrays.asList(EN_STRING, JA_STRING);
+ Files.write(tmpfile, lines);
+ List actual = Files.readAllLines(tmpfile, UTF_8);
+ assertTrue(actual.equals(lines), "Unexpected lines");
}
}
diff -r 26af21e74a8d -r 483371f41926 jdk/test/java/nio/file/Files/StreamTest.java
--- a/jdk/test/java/nio/file/Files/StreamTest.java Fri Oct 11 20:47:16 2013 +0100
+++ b/jdk/test/java/nio/file/Files/StreamTest.java Fri Oct 11 20:47:15 2013 +0100
@@ -22,11 +22,10 @@
*/
/* @test
- * @bug 8006884
- * @summary Unit test for java.nio.file.Files
- * @library ..
+ * @bug 8006884 8019526
* @build PassThroughFileSystem FaultyFileSystem
* @run testng StreamTest
+ * @summary Unit test for java.nio.file.Files methods that return a Stream
*/
import java.io.IOException;
@@ -43,11 +42,13 @@
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
+import java.util.concurrent.Callable;
import java.util.function.BiPredicate;
import java.util.stream.Stream;
import java.util.stream.Collectors;
@@ -316,56 +317,80 @@
try {
// zero lines
assertTrue(Files.size(tmpfile) == 0, "File should be empty");
+ try (Stream s = Files.lines(tmpfile)) {
+ checkLines(s, Collections.emptyList());
+ }
try (Stream s = Files.lines(tmpfile, US_ASCII)) {
- assertEquals(s.mapToInt(l -> 1).reduce(0, Integer::sum), 0, "No line expected");
+ checkLines(s, Collections.emptyList());
}
// one line
- byte[] hi = { (byte)'h', (byte)'i' };
- Files.write(tmpfile, hi);
+ List oneLine = Arrays.asList("hi");
+ Files.write(tmpfile, oneLine, US_ASCII);
+ try (Stream s = Files.lines(tmpfile)) {
+ checkLines(s, oneLine);
+ }
try (Stream s = Files.lines(tmpfile, US_ASCII)) {
- List lines = s.collect(Collectors.toList());
- assertTrue(lines.size() == 1, "One line expected");
- assertTrue(lines.get(0).equals("hi"), "'Hi' expected");
+ checkLines(s, oneLine);
}
// two lines using platform's line separator
- List expected = Arrays.asList("hi", "there");
- Files.write(tmpfile, expected, US_ASCII);
- assertTrue(Files.size(tmpfile) > 0, "File is empty");
+ List twoLines = Arrays.asList("hi", "there");
+ Files.write(tmpfile, twoLines, US_ASCII);
+ try (Stream s = Files.lines(tmpfile)) {
+ checkLines(s, twoLines);
+ }
try (Stream s = Files.lines(tmpfile, US_ASCII)) {
- List lines = s.collect(Collectors.toList());
- assertTrue(lines.equals(expected), "Unexpected lines");
+ checkLines(s, twoLines);
}
// MalformedInputException
byte[] bad = { (byte)0xff, (byte)0xff };
Files.write(tmpfile, bad);
+ try (Stream s = Files.lines(tmpfile)) {
+ checkMalformedInputException(s);
+ }
try (Stream s = Files.lines(tmpfile, US_ASCII)) {
- try {
- List lines = s.collect(Collectors.toList());
- throw new RuntimeException("UncheckedIOException expected");
- } catch (UncheckedIOException ex) {
- assertTrue(ex.getCause() instanceof MalformedInputException,
- "MalformedInputException expected");
- }
+ checkMalformedInputException(s);
}
// NullPointerException
- try {
- Files.lines(null, US_ASCII);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
- try {
- Files.lines(tmpfile, null);
- throw new RuntimeException("NullPointerException expected");
- } catch (NullPointerException ignore) { }
+ checkNullPointerException(() -> Files.lines(null));
+ checkNullPointerException(() -> Files.lines(null, US_ASCII));
+ checkNullPointerException(() -> Files.lines(tmpfile, null));
} finally {
Files.delete(tmpfile);
}
}
+ private void checkLines(Stream s, List expected) {
+ List lines = s.collect(Collectors.toList());
+ assertTrue(lines.size() == expected.size(), "Unexpected number of lines");
+ assertTrue(lines.equals(expected), "Unexpected content");
+ }
+
+ private void checkMalformedInputException(Stream s) {
+ try {
+ List lines = s.collect(Collectors.toList());
+ fail("UncheckedIOException expected");
+ } catch (UncheckedIOException ex) {
+ IOException cause = ex.getCause();
+ assertTrue(cause instanceof MalformedInputException,
+ "MalformedInputException expected");
+ }
+ }
+
+ private void checkNullPointerException(Callable> c) {
+ try {
+ c.call();
+ fail("NullPointerException expected");
+ } catch (NullPointerException ignore) {
+ } catch (Exception e) {
+ fail(e + " not expected");
+ }
+ }
+
public void testDirectoryIteratorException() throws IOException {
Path dir = testFolder.resolve("dir2");
Path trigger = dir.resolve("DirectoryIteratorException");