我发现其他人也有同样的问题,他们的问题通过在InputStreamReader构造函数中指定UTF-8来解决:
以UTF-8形式读取InputStream
这对我不起作用,我也不知道为什么。无论我尝试什么,我总是得到转义的unicode值(斜杠-U+十六进制),而不是实际的语言字符。我在这里做错了什么?提前道谢!
// InputStream is is a FileInputStream:
public void load(InputStream is) throws Exception {
BufferedReader br = null;
try {
// Passing "UTF8" or "UTF-8" to this constructor makes no difference for me:
br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String line = null;
while ((line = br.readLine()) != null) {
// The following prints "got line: chinese = \u4f60\u597d" instead of "got line: chinese = 你好"
System.out.println("got line: " + line);
}
} finally {
if (br != null) {
br.close();
}
}
}
请注意:这不是字体问题。我之所以知道这一点,是因为如果我对同一个文件使用ResourceBundle,我就会正确地获得IDE控制台中打印的中文字符。但是每当我尝试使用FileInputStream手动读取文件时,就会有一些东西不断地将字符转换为斜杠/u约定。即使我告诉它使用UTF-8编码。我也试着修改了项目的JVM参数编码,但仍然没有得到满意的结果。再次感谢你的建议。
此外,使用ResourceBundle作为最终解决方案也不是我的选择。对于这个特定的项目来说,为什么它不是一个合适的工具,为什么我要自己明确地做这件事,都是有正当理由的。
编辑:我尝试手动从InputStream中提取字节,完全绕过InputStreamReader及其构造函数,它似乎忽略了我的编码参数。这只会导致同样的行为。斜杠+U约定而不是正确的字符。很难理解为什么我不能让它的工作方式,它的工作方式似乎是每个人。我是否有某个系统/操作系统设置覆盖了Java正确处理Unicode的能力?我在Windows7版本6.1(也是64位)上使用Java版本1.8.0_65(64位)。
public void load(InputStream is) throws Exception {
String line = null;
try {
while ((line = readLine(is)) != null) {
// The following prints "got line: chinese = \u4f60\u597d" instead of "got line: chinese = 你好"
System.out.println("got line: " + line);
}
} finally {
is.close();
}
}
private String readLine(InputStream is) throws Exception {
List<Byte> bytesList = new ArrayList<>();
while (true) {
byte b = -1;
try {
b = (byte)is.read();
} catch (EOFException e) {
return bytesToString(bytesList);
}
if (b == -1) {
return bytesToString(bytesList);
}
char ch = (char)b;
if (ch == '\n') {
return bytesToString(bytesList);
}
bytesList.add(b);
}
}
private String bytesToString(List<Byte> bytesList) {
if (bytesList.isEmpty()) {
return null;
}
byte[] bytes = new byte[bytesList.size()];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = bytesList.get(i);
}
return new String(bytes, 0, bytes.length);
}
万一有其他人遇到同样的麻烦,我也能找到解决办法。由于ResourceBundle总是为我做正确的事情,我深入研究了为什么会这样,并发现java.util.properties通过loadConvert()函数发挥了所有的魔力。在BufferedReader从文件中给出一行文本后,我需要显式解码该字符串中的Unicode转义字符,大致如下所示:
public void load(InputStream is) throws Exception {
BufferedReader br = null;
try {
// Passing "UTF8" or "UTF-8" to this constructor makes no difference for me:
br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String line = null;
while ((line = br.readLine()) != null) {
// The following prints "got line: chinese = \u4f60\u597d" instead of "got line: chinese = 你好"
System.out.println("got line: " + line);
line = decodeUni(line);
// The following prints "decoded line: chinese = 你好" exactly as it should!
System.out.println("decoded line: " + line);
}
} finally {
if (br != null) {
br.close();
}
}
}
// Converts encoded "\\uxxxx" to unicode chars
private String decodeUni(String string) {
char[] charsIn = string.toCharArray();
int len = charsIn.length;
char[] charsOut = new char[len];
char ch;
int outLen = 0;
int off = 0;
int end = off + len;
while (off < end) {
ch = charsIn[off++];
// Does aChar start with "\\u" ?
if (ch == '\\') {
ch = charsIn[off++];
if(ch == 'u') {
// Yep! Convert the hex part to the correct character.
int value = 0;
for (int i = 0; i < 4; i++) {
ch = charsIn[off++];
switch (ch) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
value = (value << 4) + ch - '0';
break;
}
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': {
value = (value << 4) + 10 + ch - 'a';
break;
}
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': {
value = (value << 4) + 10 + ch - 'A';
break;
}
default: throw new IllegalArgumentException("Malformed \\uxxxx encoding: " + string);
}
}
charsOut[outLen++] = (char)value;
} else {
// Starts with a slash but not "\\u", handle the other possible escaped characters.
switch (ch) {
case 't':
ch = '\t';
break;
case 'r':
ch = '\r';
break;
case 'n':
ch = '\n';
break;
case 'f':
ch = '\f';
break;
default:
break;
}
charsOut[outLen++] = ch;
}
} else {
// Doesn't start with a slash, leave as-is.
charsOut[outLen++] = ch;
}
}
return new String(charsOut, 0, outLen).trim();
}
问题内容: 我已经创建了可执行的jar文件(使用Eclipse),在jar中包含一组图像(.png)文件。所以我添加了一个源文件夹,其中所有图像都位于项目的文件夹中。代码必须访问这些文件才能使用创建BufferedImage 较早前,为了获得我使用的路径 在执行jar时,它抛出错误 URI不是分层的 所以现在我正在使用 但是如何使ImageIO从Inputstream读取?我试过如下 抛出错误 I
问题内容: 在一个项目上,我通过一个类似于控制台的小窗口运行Java应用程序。由于这里有一个很棒的社区,我设法通过从流程输出数据来解决问题,但是由于没有输入流,我运行的命令行应用程序将不断出错。 基于该线程中最后一个有用的答复,我想我将以类似的方式实现该实现,但是在javadocs中以及整个google和互联网中寻找某个类,该类确实没有发现任何解释方法。 因此,我需要一些链接,示例,教程,示例代码
问题内容: 我必须使用SFTP从ZIP存档(只有一个文件,我知道它的名称)中获取文件内容。我唯一拥有的是ZIP的。大多数示例说明如何使用以下语句获取内容: 但是正如我所说,我的本地计算机上没有ZIP文件,也不想下载它。是够看了? UPD: 这是我的方法: 问题答案: 好吧,我已经做到了: 它可以帮助我阅读ZIP的内容而无需写入另一个文件。
我必须使用SFTP从ZIP存档(只有一个文件,我知道它的名称)获取文件内容。我唯一拥有的是ZIP的InputStream。大多数示例显示了如何使用此语句获取内容: 但正如我所说,我的本地机器上没有ZIP文件,我不想下载它。输入流是否足以读取? UPD:我就是这样做的:
我试图从一个读取。我写了下面的代码 我不明白的是我应该在一次迭代中读取多少字节?流包含保存在磁盘上的文件。 我在这里读过,但我并不真正理解这篇文章。
问题内容: 如何从BufferedImage对象获取InputStream?我尝试了这个,但是ImageIO.createImageInputStream()总是返回NULL 图片缩略图已正确生成,因为我可以成功将 bigImage绘制 到 JPanel 。 谢谢。 问题答案: 如果您尝试将图像保存到文件,请尝试: 如果您只想读取字节,请尝试执行写调用,但将其传递给ByteArrayOutputS