试图输出UTF-8文本,但它不起作用

时间:2014-08-25 07:48:09

标签: java utf-8

我有这段代码:

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;


public class Decoder {
    public static void Decode() throws IOException{
        String input = "";
        input = readFile("C:\\Users\\Dragon\\Pictures\\Binary.txt", StandardCharsets.UTF_8);
      input = input.replace(" ","");
      System.out.println(input);
      String output = "";
      Writer out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(new File("C:\\Users\\Dragon\\Pictures\\Binary2.txt")), "UTF8"));
      for(int i = 0; i <= input.length() - 8; i+=8)
      {
          int k = Integer.parseInt(input.substring(i, i+8), 2);
          out.append((char)k);
      }   
      out.close();
      System.out.println("Your File has been saved at C:\\Users\\Dragon\\Pictures\\Binary.txt");
    }
    static String readFile(String path, Charset encoding) 
              throws IOException 
            {
              byte[] encoded = Files.readAllBytes(Paths.get(path));
              return new String(encoded, encoding);
            }
}

基本上我正在做的是转换包含可以解码为文本的二进制文本文件。它成功解码,但在输出包含输出的文件时,所有UTF-8字符都替换为&#39;?&#39;。为什么会这样?

编辑: 示例输入:

00111111 01010000 01001110 01000111 00001101 00001010 00011010 00001010 00000000 00000000 00000000 00001101 01001001 01001000 01000100 01010010 00000000 00000000 00000000 00000001 00000000 00000000 00000000 00000001 00001000 00000110 00000000 00000000 00000000 00011111 00010101 00111111 00000000 00000000 00000000 00000001 01110011 01010010 01000111 01000010 00000000 00111111 00111111 00011100 00111111 00000000 00000000 00000000 00000100 01100111 01000001 01001101 01000001 00000000 00000000 00111111 00111111 00001011 00111111 01100001 00000101 00000000 00000000 00000000 00001001 01110000 01001000 01011001 01110011 00000000 00000000 00001110 00111111 00000000 00000000 00001110 00111111 00000001 00111111 01101111 00111111 01100100 00000000 00000000 00000000 00011000 01110100 01000101 01011000 01110100 01010011 01101111 01100110 01110100 01110111 01100001 01110010 01100101 00000000 01110000 01100001 01101001 01101110 01110100 00101110 01101110 01100101 01110100 00100000 00110100 00101110 00110000 00101110 00110011 00111111 00111111 01010000 00000000 00000000 00000000 00001101 01001001 01000100 01000001 01010100 00011000 01010111 01100011 00101000 00001000 01110011 01011011 00001011 00000000 00000100 00000000 00000001 00111111 00011110 01110011 00111111 00111111 00000000 00000000 00000000 00000000 01001001 01000101 01001110 01000100 00111111 01000010 01100000 00111111 

预期产出:

‰PNG


IHDR         ĉ   sRGB ®Îé   gAMA  ±üa      pHYs  à  ÃÇo¨d   tEXtSoftware paint.net 4.0.3Œæ—P   
IDATWc(s[  ºs¾²    IEND®B`‚

输出结果:

?PNG


IHDR         ?   sRGB ???   gAMA  ???a      pHYs  ?  ??o?d   tEXtSoftware paint.net 4.0.3??P   
IDATWc(s[  ?s??    IEND?B`?

2 个答案:

答案 0 :(得分:1)

您的输出是二进制数据,您应该将其写入二进制文件而不是文本文件。像这样创建输出:

OutputStream os = new FileOutputStream("output.png");

我将您的输出命名为扩展名.png,因为您的预期输出看起来像PNG图像。

并将字节写入输出,如下所示:

for(int i = 0; i <= input.length() - 8; i += 8) {
    int k = Integer.parseInt(input.substring(i, i+8), 2);
    out.write(k);
}

<强>改进:

您不必从输入字符串中删除空格,因为您可以在迭代String时跳过它们:

// If spaces are not removed:
for(int i = 0; i <= input.length() - 9; i += 9) {              // NOTE THE  +9
    int k = Integer.parseInt(input.substring(i, i+8), 2); // AND STILL +8 HERE
    out.write(k);
}

此外,您甚至不需要将整个输入文件读入内存,因为您可以通过8或9字节块读取它,因为它们为输出文件提供了有效字节。

答案 1 :(得分:0)

您的输入似乎有问题 您希望输出中包含字符¾。看着那个角色的输入我发现:

¾的整数值是十进制190(十六进制BE),二进制是10111110。 输入中与该位置对应的值等于63(00111111),即十六进制的3F。 U + 003F对应? 3f QUESTION MARK,因此您的问题在于您的输入。