Java 使用默认字符集windows-1252在JVM上显示UTF-8字符

Java 使用默认字符集windows-1252在JVM上显示UTF-8字符,java,Java,我有一个带有某种“ASCII艺术”的.txt文件,我想在cmd控制台中显示它。字符是UTF-8,但JVM的默认字符集是windows-1252。我尝试将UTF-8字符转换为bytearray,然后将bytearray转换回设置为UTF-8编码的字符串。 通过这种方法,一些字符在cmd控制台上得到了正确的描述,但许多字符被一个“?”代替,文本奇迹般地停在第二行(“ASCII艺术”要长得多) 其中一个UTF-8字符被“?”替换为“is”∩'. 该程序在我的IDE中运行良好,因为默认的字符集是UTF-

我有一个带有某种“ASCII艺术”的.txt文件,我想在cmd控制台中显示它。字符是UTF-8,但JVM的默认字符集是windows-1252。我尝试将UTF-8字符转换为bytearray,然后将bytearray转换回设置为UTF-8编码的字符串。 通过这种方法,一些字符在cmd控制台上得到了正确的描述,但许多字符被一个“?”代替,文本奇迹般地停在第二行(“ASCII艺术”要长得多)

其中一个UTF-8字符被“?”替换为“is”∩'. 该程序在我的IDE中运行良好,因为默认的字符集是UTF-8

是否可以在我的java程序中编写一个短语,告诉JVM只需切换到该程序的UTF-8字符集?或者我还能做些什么改变,以便在cmd控制台中获得这件艺术品

import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;

public class ASCIIfromtxt {
    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {

        File artFile = new File("C:/Users/MyName/IdeaProjects/ASCIIArt from Textfile/out/production/ASCIIArt from Textfile/Art.txt");
        Scanner scan = new Scanner(artFile);

        while (scan.hasNextLine()) {
            String nextLineString = scan.nextLine();
            byte[] nextLineBytes = nextLineString.getBytes();
            String win1252Str = new String(nextLineBytes, "UTF-8");
            System.out.println(win1252Str);
        }


    }
}

我认为显示全部UTF-8字符取决于正在使用的shell的能力,但在Java中,您可以使用以下代码来设置JVM编码

System.setProperty("file.encoding","UTF-8");
关于您的代码段,getBytes()方法重载有如下字符集参数

public byte[] getBytes(Charset charset)
因此,如果您想在UTF-8中真正获取字符串的字节,请使用此重载

byte[] nextLineBytes = nextLineString.getBytes(Charset.forName("UTF-8"));

我认为显示全部UTF-8字符取决于正在使用的shell的能力,但在Java中,您可以使用以下代码来设置JVM编码

System.setProperty("file.encoding","UTF-8");
关于您的代码段,getBytes()方法重载有如下字符集参数

public byte[] getBytes(Charset charset)
因此,如果您想在UTF-8中真正获取字符串的字节,请使用此重载

byte[] nextLineBytes = nextLineString.getBytes(Charset.forName("UTF-8"));

例如,您使用的特定字符是通过Cp1252到UTF-8的圆形可折叠字符。问题是,您试图将UTF-8字符打印到字符集为Cp1252的控制台,因此该字符不可用,而是将呈现为字符

但是,如果您尝试映射Cp1252中未映射的字节序列(即0x81、0x8D、0x8F、0x90和0x9D)将全部映射到
(0x3F),您当前的解决方案将失败,并且最好使用特定字符集初始化扫描仪:

Scanner scan=新扫描器(文件,StandardCharsets.UTF_8);
要执行您想要执行的操作,您可能需要在运行应用程序之前更改终端的代码页(尽管这并不总是达到预期效果):


例如,您使用的特定字符是通过Cp1252到UTF-8的圆形可折叠字符。问题是,您试图将UTF-8字符打印到字符集为Cp1252的控制台,因此该字符不可用,而是将呈现为字符

但是,如果您尝试映射Cp1252中未映射的字节序列(即0x81、0x8D、0x8F、0x90和0x9D)将全部映射到
(0x3F),您当前的解决方案将失败,并且最好使用特定字符集初始化扫描仪:

Scanner scan=新扫描器(文件,StandardCharsets.UTF_8);
要执行您想要执行的操作,您可能需要在运行应用程序之前更改终端的代码页(尽管这并不总是达到预期效果):


String.getBytes
与UTF-8一起使用会导致不良行为,因为OP正在尝试使用Cp1252将读取的UTF-8字节重新配置为字符串。这意味着OP首先需要获取字节,因此他们需要使用Cp1252(本例中的默认编码)将字符串解码回字节,然后使用UTF-8使用这些字节创建一个字符串。请注意,该方案并不总是有效的,因为有些字节没有映射到Cp1252中。将
String.getBytes
与UTF-8一起使用会导致不良行为,因为OP试图使用Cp1252将UTF-8字节重新构造为字符串。这意味着OP首先需要获取字节,因此他们需要使用Cp1252(本例中的默认编码)将字符串解码回字节,然后使用UTF-8使用这些字节创建一个字符串。请注意,该方案并不总是有效的,因为有些字节没有映射到Cp1252中。