在Java中无法正确读取二进制文件

时间:2014-04-21 18:02:58

标签: java file-io binaryfiles

我正在尝试使用bufferedReader在Java中读取二进制文件。我用“UTF-8”编码写了那个二进制文件。写入二进制文件的代码:

  byte[] inMsgBin=null;
  try {
      inMsgBin = String.valueOf(cypherText).getBytes("UTF-8");
      //System.out.println("CIPHER TEXT:FULL:BINARY WRITE: "+inMsgBin);
  } catch (UnsupportedEncodingException ex) {
      Logger.getLogger(EncDecApp.class.getName()).log(Level.SEVERE, null, ex);
  }
  try (FileOutputStream out = new FileOutputStream(fileName+ String.valueOf(new SimpleDateFormat("yyyyMMddhhmm").format(new Date()))+ ".encmsg")) {
      out.write(inMsgBin);
      out.close();
  } catch (IOException ex) {
      Logger.getLogger(EncDecApp.class.getName()).log(Level.SEVERE, null, ex);
  }       


System.out.println("cypherText charCount="+cypherText.length());

这里'cypherText'是一个包含一些内容的String。文件中写入的字符总数为19。在写入之后,当我在Notepad ++中打开二进制文件时,它会显示一些字符。选择文件的所有内容总共计为19个字符。

现在,当我使用BufferedReader读取相同的文件时,使用以下代码行:

try
        {
        DecMessage obj2= new DecMessage();
          StringBuilder cipherMsg=new StringBuilder();

            try (BufferedReader in = new BufferedReader(new FileReader(filePath))) {
                String tempLine="";
                fileSelect=true;
                while ((tempLine=in.readLine()) != null) {                      
                    cipherMsg.append(tempLine);
                }
            }

System.out.println("FROM FILE: charCount= "+cipherMsg.length());

这里读取的字符总数(存储在'charCount'中)是17而不是19。

如何正确阅读文件的所有字符?

1 个答案:

答案 0 :(得分:1)

在读取文件时指定相同的字符集。

   try (final BufferedReader br = Files.newBufferedReader(new File(filePath).toPath(),
                    StandardCharsets.UTF_8))

更新

现在我遇到了你的问题。谢谢你的文件。

再次说明:您的文件仍然可以读取任何文本阅读器,例如Notepad ++(因为您的字符包含扩展名和控制字符,您看到的是那些不可读的字符。但它仍然是ASCII格式。)

现在回到你的问题,你的代码有两个问题。

  1. 在阅读文件时,您应指定正确的字符集。读者是字符读者 - 字节在阅读时会被转换为字符。如果您指定Charset,它将使用其他它将使用默认系统字符集。因此,您应该按如下方式创建BufferedReader

    try(final BufferedReader br = Files.newBufferedReader(new File(filePath).toPath(),                     StandardCharsets.UTF_8))

  2. 第二个问题,您有包含控制字符的字符。在逐行读取文件时,默认情况下,bufferedReader使用系统的默认EOL字符并跳过这些字符。这就是为什么你得到17而不是19(因为你有2个字符是CR)。为避免此问题,您应阅读字符。

    int ch;             while((ch = br.read())> -1){                 buffer.append((char)的CH);             }

  3. 总的来说,下面的方法会返回正确的文字。

    static String readCyberText() {
            StringBuilder buffer = new StringBuilder();
            try (final BufferedReader br = Files.newBufferedReader(new File("C:\\projects\\test2201404221017.txt").toPath(),
                    StandardCharsets.UTF_8)){
                int ch;
                while ((ch = br.read()) > -1) {
                    buffer.append((char)ch);
                }
                return buffer.toString();
            }
            catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
    

    你可以通过

    进行测试
    String s = readCyberText();
        System.out.println(s.length());
        System.out.println(s);
    

    并输出为

    19
    ia@
    
    m©Ù6ë<«9K()il
    

    注意:String的长度为19,但是当它显示时它只显示17个字符。因为控制台被视为eof并显示在不同的行中。但是String正确地包含了所有19个字符。