Java CSVhelper writeLine,在for循环过程中处于中间位置的空指针
对于一个java模拟项目,我有一个日志文件,可以跟踪在一次运行期间发生的所有事情。为此,我将自定义TimeLog.class的对象添加到列表中。模拟完成后,我循环浏览此列表,为每个条目编写字符串数组列表,然后使用我在网上找到的以下“CSVHelper”类将其写入csv文件(归功于Keke Chen) 正在创建字符串的ArrayList:Java CSVhelper writeLine,在for循环过程中处于中间位置的空指针,java,csv,for-loop,nullpointerexception,string-length,Java,Csv,For Loop,Nullpointerexception,String Length,对于一个java模拟项目,我有一个日志文件,可以跟踪在一次运行期间发生的所有事情。为此,我将自定义TimeLog.class的对象添加到列表中。模拟完成后,我循环浏览此列表,为每个条目编写字符串数组列表,然后使用我在网上找到的以下“CSVHelper”类将其写入csv文件(归功于Keke Chen) 正在创建字符串的ArrayList: public static void saveData(List<TimeLog> data, String fileName, Simulator
public static void saveData(List<TimeLog> data, String fileName, Simulator simulator,
ArrayList<String> header) throws Exception {
File csvFile = new File(simulator.getOutputFolder()+fileName);
FileOutputStream fos = new FileOutputStream(csvFile);
Writer fw = new OutputStreamWriter(fos, "UTF-8");
CSVHelper.writeLine(fw, header);
for (TimeLog entry : data) {
ArrayList<String> row = new ArrayList<>();
row.add(String.valueOf(entry.getTime())); //time of entry, double
row.add(String.valueOf(entry.getMessageType())); //type of message (SETUP, DEBUG, EVENT, ERROR)
if (entry.getEvent() == null) {
row.add("");
} else {
row.add(entry.getEvent().getTypeName()); //event type if event
}
row.add(entry.getLog()); //message
CSVHelper.writeLine(fw, row);
}
fw.flush();
fw.close();
}
由于Emax的评论,我注意到了其他一些东西。我补充说
System.out.println("0:"+row.get(0)+", 1:"+row.get(1)+", 2:"+row.get(2)+", 3:"+row.get(3));
在saveData方法中,就在CSVHelper.writeLine(fw,row)之前,在写入字符串之前查看字符串列表。这会在控制台中生成完整的日志列表,也会生成未(或部分)写入csv文件的日志列表。不知何故,TimeLog for循环在writeLine抛出异常时继续
编辑2:TimeLog的结构:
public class TimeLog {
private double time;
private MessageType mt;
private String log;
private Event e;
public TimeLog(double time, MessageType mt, String log, Event e) {
this.time = time;
this.mt = mt;
this.log = log;
this.e = e;
}
//see full method above
public static void saveData(List<TimeLog> data, String fileName, Simulator simulator,
ArrayList<String> header) throws Exception { ...
//further more, there are some getters
}
请记住,0:、1:、2:、3:不在原始列表中,而是添加到println()方法中
更新:使用Emax的打印返回null的值的想法揭示了问题。val的值确实变为null,它发生在NullPointerException(没有消息)处,因此e.getMessage()返回null。更糟糕的是,编写器并没有将所有值写入csv文件,但似乎有某种延迟(可能在实际将其写入文件或其他文件之前,它首先收集默认数量的字符?)。因此,我认为空指针是在通过val的循环过程中发生的,而它已经完成了。谢谢你的帮助 导致该行出现NullPointerException的唯一可能原因是val为null,因为val是从列表中获取的,因此问题最多可归结为:
row.add(String.valueOf(entry.getTime()));
row.add(String.valueOf(entry.getMessageType()));
row.add(entry.getEvent().getTypeName());
row.add(entry.getLog());
其中一个add正在向列表中添加null,您应该检查其中一个。
但是,发布完整的stracktrace,包括(如果存在)“原因”
更新
尝试按如下方式修改writeLine:
[...]
if (!firstVal) {
w.write(",");
}
w.write("\"");
// EDIT HERE
if (val == null) {
System.out.println("This val is null: " + values);
}
// .....
for (int i = 0; i < val.length(); i++) {
[...]
[…]
如果(!firstVal){
w、 写(“,”;
}
w、 写(\);
//编辑这里
if(val==null){
System.out.println(“此val为空:+值);
}
// .....
对于(int i=0;i
用导致NullPointerException的大小写发布输出,这就是我所想的,但是创建的文件在最后一个单元格中也包含字符串值。刚才,最后一个单元格包含消息的开头,但中途停止。变量val在for循环期间没有更改,并且包含可写字符,但循环只包含stops.@MRommers您好,您能发布straktrace和一个您正在传递给Method的列表数据示例吗异常的StackTrace是第一个要检查的信息源!至少要获得引发异常的正确行。@MRommers发布TimeLog类的结构和一个实例示例t您正在将as list传递给saveDatamethod@MRRommers也许我知道了!stacktrace指向第73行的TimeLog.java,检查(ArrayList头)包含null!!!!很抱歉让您失望,标题不包含null,此行也正确写入csv文件,writeLine方法比第一行更远。TimeLog第73行包含:CSVHelper.writeLine(fw,第行);顺便说一句,为什么不将您的
TimeLog
字段设置为final
?还有,涉及多少线程?填充时,列表有可能被多个线程修改吗?
System.out.println("0:"+row.get(0)+", 1:"+row.get(1)+", 2:"+row.get(2)+", 3:"+row.get(3));
public class TimeLog {
private double time;
private MessageType mt;
private String log;
private Event e;
public TimeLog(double time, MessageType mt, String log, Event e) {
this.time = time;
this.mt = mt;
this.log = log;
this.e = e;
}
//see full method above
public static void saveData(List<TimeLog> data, String fileName, Simulator simulator,
ArrayList<String> header) throws Exception { ...
//further more, there are some getters
}
0:27131.490112666303, 1:EVENT, 2:TOOLEVENT, 3:Tool input event, item 3998 has gone into tool QSD301
row.add(String.valueOf(entry.getTime()));
row.add(String.valueOf(entry.getMessageType()));
row.add(entry.getEvent().getTypeName());
row.add(entry.getLog());
[...]
if (!firstVal) {
w.write(",");
}
w.write("\"");
// EDIT HERE
if (val == null) {
System.out.println("This val is null: " + values);
}
// .....
for (int i = 0; i < val.length(); i++) {
[...]