0

I have used PrintWriter for long time and I have never encounted with this problem. See below

When I open the csv file using excel the first element of the headerline disapeared. enter image description here

To further investigate, I found a couple of blank lines inserted at the beginning when opening it using text file.

enter image description here

below is my code:

print header line:

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();
    }
    
}

print actual data:

    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();        
        }
    }

the file writer code:

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;
    }

}
Jack
  • 1,339
  • 1
  • 12
  • 31
  • 1
    Please try to clean up your code and try to provide [_minimal_ reproducible example](https://stackoverflow.com/help/minimal-reproducible-example)/ It is very likely that you re-read and re-write the file each time when you should be just appending a new line. It's a huge overkill. – Nowhere Man Jul 04 '20 at 15:22
  • I have a Hub Object. each of them (total of 300 hubs) will call printHubSummary(Hub hub, String filePath) every 60min. would it be the issue of "re-read and re-write"? I just need to add a new line. could you suggest the workaround? – Jack Jul 04 '20 at 17:53

1 Answers1

2

I don't know if this is the only problem with your code, but every call to your FileWriter.writeFile adds a new Byte Order Marker to the file. This means you end up with several markers in the file, and this may confuse some tools.

To remove the extra BOM in FileWriter.writeFile, you can use the deleteCharAt method:

    ...
    buf = buf.append(System.getProperty("line.separator"));
}
if (buf.length() > 0 && buf.charAt(0) == '\uFEFF') {
    buf.deleteCharAt(0);
}
buf.append(filein);
Joni
  • 108,737
  • 14
  • 143
  • 193
  • add this part will report "java.lang.StringIndexOutOfBoundsException: index 0,length 0" – Jack Jul 04 '20 at 17:57
  • So check if the string is empty first – Joni Jul 04 '20 at 18:00
  • it appears to solve this problem but it looks the program is running a lot slower. I am not sure the issue mentioned by Alex is fixed (i.e. potentional duplicated re-read and re-write the file each time when there should be just appending a new line each time it's called by a hub object to write. Is there a huge overkill?) – Jack Jul 04 '20 at 18:10
  • Running a lot slower than what? Yes the writeFile function re-reads the whole file every time it's called even if it's to add one single line, so it's not "optimal" if you're writing files with thousands of lines, but it's good enough for smaller files – Joni Jul 05 '20 at 02:25
  • I often face writing huge files. Could you suggest code modification to speed up the reading and writing process? – Jack Jul 05 '20 at 13:29
  • There's a "boolean append" constructor parameter for FileOutputStream, if you set it to `true` the existing contents of the file are kept and anything you write will automatically go to the end of the file. See also https://stackoverflow.com/questions/1625234/how-to-append-text-to-an-existing-file-in-java – Joni Jul 05 '20 at 13:32
  • Hi Joni, I just find out that my program running is gradually slowed down to an unacceptable level due to the PrintWriter. When I disable writing operations, the program is runing super fast. It looks like the current appoach (as shown above) is the show stopper. Could you advice the workaround? thank you – Jack Jul 06 '20 at 18:06