【问题标题】:Java PrintWriter printing multiple blank lines at the beginning of each fileJava PrintWriter 在每个文件的开头打印多个空行
【发布时间】:2020-07-04 15:04:23
【问题描述】:

我使用 PrintWriter 很久了,从来没有遇到过这个问题。见下文

当我使用 excel 打开 csv 文件时,标题行的第一个元素消失了。

为了进一步调查,我发现使用文本文件打开它时,在开头插入了几行空行。

下面是我的代码:

打印标题行:

public void printHubInboundHeader() {
    try {
        StringBuilder sb = new StringBuilder();
        String headingPart1 = "Inbound_Hub, Date, Time,";
        String headingPart2 = "Weight";
                    
        sb.append(headingPart1+headingPart2);
        System.out.println(sb);
        FileWriter.writeFile(sb.toString(),"filepath");
    }
    catch(Exception e) {
        System.out.println("Something wrong when writting headerline");
        e.printStackTrace();
    }
    
}

打印实际数据:

    public void printHubSummary(Hub hub, String filePath) {
        
        try {
            StringBuilder sb = new StringBuilder();   
            
            String h = hub.getHub_code();
            String date = Integer.toString(hub.getGs().getDate());
            String time = hub.getGs().getHHMMFromMinute(hub.getGs().getClock());
            String wgt = Double.toString(hub.getIb_wgt());

                    
            sb.append(h+","+date+","+time+","+wgt);
//          System.out.println("truck print line: " + sb);
            FileWriter.writeFile(sb.toString(),filePath);
        }
        
        catch (Exception e) {
            System.out.println("Something wrong when outputing truck summary file!");
            e.printStackTrace();        
        }
    }

文件编写器代码:

public class FileWriter {
    private static String filenameTemp;

    public static boolean creatFile(String name) throws IOException {
        boolean flag = false;
        filenameTemp = name + "";
        System.out.println("write to file: "+filenameTemp);
        File filename = new File(filenameTemp);
        if (!filename.exists()) {
            filename.createNewFile();
            flag = true;
        }
        else {
            filename.delete();
            filename.createNewFile();
            flag = true;
        }
        return flag;
    }

    public static boolean writeFile(String newStr, String filename) throws IOException {
        boolean flag = false;
        String filein = newStr + "\r\n";
        String temp = "";

        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;

        FileOutputStream fos = null;
        PrintWriter pw = null;
        try {
            File file = new File(filename);
            fis = new FileInputStream(file);
            isr = new InputStreamReader(fis);
            br = new BufferedReader(isr);
            StringBuffer buf = new StringBuffer();

            for (int j = 1; (temp = br.readLine()) != null; j++) {
                buf = buf.append(temp);
                buf = buf.append(System.getProperty("line.separator"));
            }
            buf.append(filein);

            fos = new FileOutputStream(file);
            byte[] unicode = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
            fos.write(unicode);
            pw = new PrintWriter(fos);
            
            pw.write(buf.toString().toCharArray());
            pw.flush();
            flag = true;
        } catch (IOException e1) {
            throw e1;
        } finally {
            if (pw != null) {
                pw.close();
            }
            if (fos != null) {
                fos.close();
            }
            if (br != null) {
                br.close();
            }
            if (isr != null) {
                isr.close();
            }
            if (fis != null) {
                fis.close();
            }
        }
        return flag;
    }
    
    public static void setFileName(String fileName){
        filenameTemp = fileName;
    }

}

【问题讨论】:

  • 请尝试清理您的代码并尝试提供minimal reproducible example/ 当您应该只是追加一个新行时,您很可能每次都重新读取和重新写入文件。这是一个巨大的矫枉过正。
  • 我有一个 Hub 对象。他们每个人(总共 300 个集线器)将每 60 分钟调用一次 printHubSummary(Hub hub, String filePath)。会是“重读重写”的问题吗?我只需要添加一个新行。您能建议解决方法吗?

标签: java csv printwriter


【解决方案1】:

我不知道这是否是您的代码的唯一问题,但每次调用您的FileWriter.writeFile 都会在文件中添加一个新的字节顺序标记。这意味着您最终会在文件中使用多个标记,这可能会使某些工具感到困惑。

要删除FileWriter.writeFile中多余的BOM,可以使用deleteCharAt方法:

    ...
    buf = buf.append(System.getProperty("line.separator"));
}
if (buf.length() > 0 && buf.charAt(0) == '\uFEFF') {
    buf.deleteCharAt(0);
}
buf.append(filein);

【讨论】:

  • 添加这部分会报“java.lang.StringIndexOutOfBoundsException: index 0,length 0”
  • 所以先检查字符串是否为空
  • 它似乎解决了这个问题,但看起来程序运行得慢了很多。我不确定亚历克斯提到的问题是否已解决(即每次被集线器对象调用写入时应该只附加一个新行时,潜在的重复重新读取和重新写入文件。是否有一个巨大的矫枉过正?)
  • 运行速度比什么慢很多?是的,writeFile 函数在每次调用时都会重新读取整个文件,即使它要添加一行,所以如果你正在编写包含数千行的文件,它并不是“最佳”的,但对于较小的文件来说已经足够了
  • 我经常面临写大文件的问题。您能否建议修改代码以加快读写过程?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-01
  • 2021-09-20
相关资源
最近更新 更多