8276970: Default charset for PrintWriter that wraps PrintStream
Reviewed-by: rriggs, alanb
This commit is contained in:
parent
29e552c03a
commit
231fb61aae
@ -99,7 +99,9 @@ public class OutputStreamWriter extends Writer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an OutputStreamWriter that uses the default character encoding.
|
||||
* Creates an OutputStreamWriter that uses the default character encoding, or
|
||||
* where {@code out} is a {@code PrintStream}, the charset used by the print
|
||||
* stream.
|
||||
*
|
||||
* @param out An OutputStream
|
||||
* @see Charset#defaultCharset()
|
||||
@ -107,7 +109,7 @@ public class OutputStreamWriter extends Writer {
|
||||
public OutputStreamWriter(OutputStream out) {
|
||||
super(out);
|
||||
se = StreamEncoder.forOutputStreamWriter(out, this,
|
||||
Charset.defaultCharset());
|
||||
out instanceof PrintStream ps ? ps.charset() : Charset.defaultCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -68,6 +68,7 @@ public class PrintStream extends FilterOutputStream
|
||||
private final boolean autoFlush;
|
||||
private boolean trouble = false;
|
||||
private Formatter formatter;
|
||||
private final Charset charset;
|
||||
|
||||
/**
|
||||
* Track both the text- and character-output streams, so that their buffers
|
||||
@ -108,7 +109,8 @@ public class PrintStream extends FilterOutputStream
|
||||
private PrintStream(boolean autoFlush, OutputStream out) {
|
||||
super(out);
|
||||
this.autoFlush = autoFlush;
|
||||
this.charOut = new OutputStreamWriter(this);
|
||||
this.charset = out instanceof PrintStream ps ? ps.charset() : Charset.defaultCharset();
|
||||
this.charOut = new OutputStreamWriter(this, charset);
|
||||
this.textOut = new BufferedWriter(charOut);
|
||||
}
|
||||
|
||||
@ -124,7 +126,8 @@ public class PrintStream extends FilterOutputStream
|
||||
/**
|
||||
* Creates a new print stream, without automatic line flushing, with the
|
||||
* specified OutputStream. Characters written to the stream are converted
|
||||
* to bytes using the default charset.
|
||||
* to bytes using the default charset, or where {@code out} is a
|
||||
* {@code PrintStream}, the charset used by the print stream.
|
||||
*
|
||||
* @param out The output stream to which values and objects will be
|
||||
* printed
|
||||
@ -139,7 +142,8 @@ public class PrintStream extends FilterOutputStream
|
||||
/**
|
||||
* Creates a new print stream, with the specified OutputStream and line
|
||||
* flushing. Characters written to the stream are converted to bytes using
|
||||
* the default charset.
|
||||
* the default charset, or where {@code out} is a {@code PrintStream},
|
||||
* the charset used by the print stream.
|
||||
*
|
||||
* @param out The output stream to which values and objects will be
|
||||
* printed
|
||||
@ -201,6 +205,7 @@ public class PrintStream extends FilterOutputStream
|
||||
this.autoFlush = autoFlush;
|
||||
this.charOut = new OutputStreamWriter(this, charset);
|
||||
this.textOut = new BufferedWriter(charOut);
|
||||
this.charset = charset;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1374,4 +1379,12 @@ public class PrintStream extends FilterOutputStream
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return the charset used in this {@code PrintStream} instance}
|
||||
*
|
||||
* @since 18
|
||||
*/
|
||||
public Charset charset() {
|
||||
return charset;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,8 @@ public class PrintWriter extends Writer {
|
||||
* Creates a new PrintWriter, without automatic line flushing, from an
|
||||
* existing OutputStream. This convenience constructor creates the
|
||||
* necessary intermediate OutputStreamWriter, which will convert characters
|
||||
* into bytes using the default charset.
|
||||
* into bytes using the default charset, or where {@code out} is a
|
||||
* {@code PrintStream}, the charset used by the print stream.
|
||||
*
|
||||
* @param out An output stream
|
||||
*
|
||||
@ -132,8 +133,9 @@ public class PrintWriter extends Writer {
|
||||
/**
|
||||
* Creates a new PrintWriter from an existing OutputStream. This
|
||||
* convenience constructor creates the necessary intermediate
|
||||
* OutputStreamWriter, which will convert characters into bytes using the
|
||||
* default charset.
|
||||
* OutputStreamWriter, which will convert characters into bytes using
|
||||
* the default charset, or where {@code out} is a {@code PrintStream},
|
||||
* the charset used by the print stream.
|
||||
*
|
||||
* @param out An output stream
|
||||
* @param autoFlush A boolean; if true, the {@code println},
|
||||
@ -144,7 +146,7 @@ public class PrintWriter extends Writer {
|
||||
* @see Charset#defaultCharset()
|
||||
*/
|
||||
public PrintWriter(OutputStream out, boolean autoFlush) {
|
||||
this(out, autoFlush, Charset.defaultCharset());
|
||||
this(out, autoFlush, out instanceof PrintStream ps ? ps.charset() : Charset.defaultCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
|
107
test/jdk/java/io/PrintStream/InheritEncodingTest.java
Normal file
107
test/jdk/java/io/PrintStream/InheritEncodingTest.java
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8276970
|
||||
* @summary Test to verify the charset in PrintStream is inherited
|
||||
* in the OutputStreamWriter/PrintWriter
|
||||
* @run testng InheritEncodingTest
|
||||
*/
|
||||
@Test
|
||||
public class InheritEncodingTest {
|
||||
|
||||
private static final String testString = "\u00e9\u3042"; // "éあ"
|
||||
|
||||
@DataProvider
|
||||
public Object[][] encodings() {
|
||||
return new Object[][]{
|
||||
{StandardCharsets.ISO_8859_1},
|
||||
{StandardCharsets.US_ASCII},
|
||||
{StandardCharsets.UTF_8},
|
||||
{StandardCharsets.UTF_16},
|
||||
{StandardCharsets.UTF_16BE},
|
||||
{StandardCharsets.UTF_16LE},
|
||||
};
|
||||
}
|
||||
|
||||
@Test (dataProvider = "encodings")
|
||||
public void testOutputStreamWriter(Charset stdCharset) throws IOException {
|
||||
var ba = new ByteArrayOutputStream();
|
||||
var ps = new PrintStream(ba, true, stdCharset);
|
||||
var expected = new String(testString.getBytes(stdCharset), stdCharset);
|
||||
|
||||
// tests OutputStreamWriter's encoding explicitly
|
||||
var osw = new OutputStreamWriter(ps);
|
||||
assertEquals(Charset.forName(osw.getEncoding()), stdCharset);
|
||||
|
||||
// tests roundtrip result
|
||||
osw.write(testString);
|
||||
osw.flush();
|
||||
var result = ba.toString(stdCharset);
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
|
||||
@Test (dataProvider = "encodings")
|
||||
public void testPrintWriter(Charset stdCharset) throws IOException {
|
||||
var ba = new ByteArrayOutputStream();
|
||||
var ps = new PrintStream(ba, true, stdCharset);
|
||||
var expected = new String(testString.getBytes(stdCharset), stdCharset);
|
||||
|
||||
// tests roundtrip result
|
||||
var pw = new PrintWriter(ps);
|
||||
pw.write(testString);
|
||||
pw.flush();
|
||||
var result = ba.toString(stdCharset);
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
|
||||
@Test (dataProvider = "encodings")
|
||||
public void testPrintStream(Charset stdCharset) throws IOException {
|
||||
var ba = new ByteArrayOutputStream();
|
||||
var ps = new PrintStream(ba, true, stdCharset);
|
||||
var expected = new String(testString.getBytes(stdCharset), stdCharset);
|
||||
|
||||
// tests PrintStream's charset explicitly
|
||||
var psWrapper = new PrintStream(ps);
|
||||
assertEquals(psWrapper.charset(), stdCharset);
|
||||
|
||||
// tests roundtrip result
|
||||
psWrapper.print(testString);
|
||||
psWrapper.flush();
|
||||
var result = ba.toString(stdCharset);
|
||||
assertEquals(result, expected);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user