【问题标题】:set encoding as UTF-8 for a FileWriter [duplicate]将 FileWriter 的编码设置为 UTF-8 [重复]
【发布时间】:2016-05-10 00:45:42
【问题描述】:

下面是我的代码,它打算获取两个 .ckl 文件,比较两者,添加新项目并创建一个新的合并文件。该程序在 Netbeans 中运行时可以正确执行,但是在执行 .jar 时,该程序似乎没有以 UTF-8 对文件进行编码。我对编程比较陌生,想知道我可能需要在哪里或如何强制执行这种编码?

** 我删除了 Swing 代码和其他行,以便只显示我的方法,该方法执行所有比较和合并。

public void mergeFiles(File[] files, File mergedFile) {

    ArrayList<String> list = new ArrayList<String>();

    FileWriter fstream = null;
    BufferedWriter out = null;
    try {
        fstream = new FileWriter(mergedFile, false);
        out = new BufferedWriter(fstream);
      } catch (IOException e1) {
        e1.printStackTrace();
    }
    // Going in a different direction. We are using a couple booleans to tell us when we want to copy or not. So at the beginning since we start
    // with our source file we set copy to true, we want to copy everything and insert vuln names into our list as we go. After that first file 
    // we set the boolean to false so that we dont start copying anything from the second file until it is a vuln. We set to true when we see vuln
    // and set it to false if we already have that in our list. 
    // We have a tmpCopy to store away the value of copy when we see a vuln, and reset it to that value when we see an </VULN>
    Boolean copy = true;
    Boolean tmpCopy = true;
    for (File f : files) {
        textArea1.append("merging files into: " + mergedFilePathway + "\n");
        FileInputStream fis;
        try {
            fis = new FileInputStream(f);
//                BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(mergedFile), "UTF-8"));
            BufferedReader in = new BufferedReader(new InputStreamReader(fis));
            String aLine;
            while ((aLine = in.readLine()) != null) {
                // Skip the close checklist and we can write it in at the end
                if (aLine.trim().equals("</iSTIG>")) {
                    continue;
                }
                if (aLine.trim().equals("</STIGS>")) {
                    continue;
                }
                if (aLine.trim().equals("</CHECKLIST>")) {
                    continue;
                }
                if (aLine.trim().equals("<VULN>")) {
                    // Store our current value of copy
                    tmpCopy = copy;
                    copy = true;
                    String aLine2 = in.readLine();
                    String aLine3 = in.readLine();
                    String nameLine = in.readLine();

                    if (list.contains(nameLine.trim())) {
                        textArea1.append("Skipping: " + nameLine + "\n");
                        copy = false;
                        while (!(aLine.trim().equals("</VULN>"))) {
                            aLine = in.readLine();
                        }
                        continue; // this would skip the writing out to file part
                    } else {
                        list.add(nameLine.trim());
                        textArea1.append("::: List is now :::");
                        textArea1.append(list.toString() + "\n");
                    }
                    if (copy) {
                        out.write(aLine);
                        out.newLine();
                        out.write(aLine2);
                        out.newLine();
                        out.write(aLine3);
                        out.newLine();
                        out.write(nameLine);
                        out.newLine();
                    }
                } else if (copy) {
                    out.write(aLine);
                    out.newLine();
                }
                // after we have written to file, if the line was a close vuln, switch copy back to original value
                if (aLine.trim().equals("</VULN>")) {
                    copy = tmpCopy;
                }
            }

            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        copy = false;
    }

    // Now lets add the close checklist tag we omitted before
    try {
        out.write("</iSTIG>");
        out.write("</STIGS>");
        out.write("</CHECKLIST>");
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}                                        

【问题讨论】:

  • 那是很多代码。请编辑您的问题并删除所有 Swing 代码,因为它与您的问题无关。我很确定只有 mergeFiles 方法是相关的。
  • 谢谢,我已经删除了似乎没有必要的代码。我们现在剩下的是比较和合并的方法。
  • 你删除的太多了。整个 mergeFiles 方法需要在您的问题中,尤其是创建 out 的代码行,因为这很可能是您的问题的原因。
  • 我很抱歉,我没有意识到我已经删除了这么多。现在显示了整个 mergeFiles 方法。

标签: java encoding utf-8


【解决方案1】:

Java 有extensive, highly informative documentation。保留它的书签。有困难时先参考它。您会发现它经常很有帮助。

在这种情况下,documentation for FileWriter 表示:

此类的构造函数假定默认字符编码和默认字节缓冲区大小是可以接受的。要自己指定这些值,请在 FileOutputStream 上构造一个 OutputStreamWriter。

如果您想确保您的文件将被写入为 UTF-8,请替换为:

FileWriter fstream = null;
BufferedWriter out = null;
try {
    fstream = new FileWriter(mergedFile, false);

用这个:

Writer fstream = null;
BufferedWriter out = null;
try {
    fstream = new OutputStreamWriter(new FileOutputStream(mergedFile), StandardCharsets.UTF_8);

【讨论】:

    【解决方案2】:

    对于那些使用FileWriter 来追加到现有文件的人,以下将起作用

    try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), StandardCharsets.UTF_8)) {
    
        //code
    
    }
    

    【讨论】:

    • 实际上,鉴于您关注的是附加情况,这似乎是一个有效的答案,因此我认为不应该作为评论发布。以后,等有声望再说吧。属于 cmets 的答案会被删除
    • 应该避免这种结构,首选try (FileOutputStream fos = ...; OutputStreamWriter osw = ...(fos); BufferWriter bw = new BufferedWriter(osw)) {。否则,如果在随后执行的构造函数中发生异常,中间对象将不会调用 close()。例如,如果 BufferedWriter() 有异常(在这种特殊情况下极不可能),则 OutputStreamWriterFileOutputStream 实例将不会调用 close()。见Java 8 JLS
    • @neuralmer -- 很好的点。试图解释 -- 当我们有 AutoCloseable 资源对象的嵌套包装时(这里 BufferedReader 包装 OutputStreamWriter 包装 FileOutputStream),而不是在最外层的包装对象上有一个 try-with-one-resource 语句,最好有一个 try-with-multiple-resources 语句,然后中断嵌套实例化。到 try 子句的多个单独的资源初始化语句中。那里。唷。那是我满口的。我敢肯定你的眼睛会呆滞的。 :-)
    【解决方案3】:

    您可以使用命令java -Dfile.encoding=UTF-8 -jar yourjar.jar 运行它。

    关注this了解更多信息。

    【讨论】:

      猜你喜欢
      • 2015-03-23
      • 2012-03-10
      • 2012-02-01
      • 2016-09-22
      • 2012-05-26
      • 1970-01-01
      • 2018-02-17
      • 2013-01-18
      • 2013-05-07
      相关资源
      最近更新 更多