for循环仅返回最后值:twitter4j导出推特到CSV的异常问题
问题根源定位
- 核心写入异常:你把
PrintWriter、StringBuilder、CSV表头的写入逻辑全部放在遍历每条推特的for循环内部。每轮循环都会重新创建PrintWriter实例,该类默认以覆盖写模式打开目标文件——打开瞬间就会把文件原有内容全部清空,然后写入当前轮次的内容,再执行close。等所有循环跑完,文件里自然只剩最后一轮写入的内容,和你观察到的「控制台能输出所有推特、每轮循环都打印done、CSV仅保留最后一条值」的表现完全匹配。 - 冗余逻辑错误:在单条推特的处理分支里嵌套了
for(int i=0; i<20; i++)的循环,会导致同一条推特被重复写入20次。原本作为行序号的i应该是全局自增的计数变量,不需要在单条数据的处理中反复遍历。
修正方案
- 将文件写流对象、
StringBuilder实例、CSV表头构造全部移到推特遍历循环的外部,保证整个写入流程仅打开一次文件、仅写入一次表头,不会在遍历过程中反复清空文件内容。 - 定义全局行序号计数器,每处理完一条推特就自增1,移除无意义的20次嵌套循环。
- 等所有推特内容全部拼接完成后,再统一执行文件写入、关闭写流。
修正后的可运行代码
Twitter twitter1 = TwitterFactory.getSingleton(); List<Status> statuses = twitter1.getUserTimeline(); System.out.println("Showing home timeline."); // 以下逻辑全部移到循环外,仅初始化一次 PrintWriter pw = new PrintWriter(new File("/Desktop/cwk/4104/tweets.csv")); StringBuilder sb = new StringBuilder(); // 仅写入一次CSV表头 sb.append("ID,UserId,Username,Name,Location,Tweet\n"); // 全局行序号计数器 int rowIndex = 1; for (Status status : statuses) { System.out.println(status.getUser().getScreenName() + ":" + status.getText()); // 逐条拼接推特内容到字符串构造器 sb.append(rowIndex); sb.append(","); sb.append(status.getUser().getId()); sb.append(","); sb.append(status.getUser().getScreenName()); sb.append(","); sb.append(status.getUser().getName()); sb.append(","); sb.append(status.getUser().getLocation()); sb.append(","); sb.append(status.getText()); sb.append("\n"); // 序号自增 rowIndex++; } // 所有内容拼接完成后统一写入、关闭流 pw.write(sb.toString()); pw.close(); System.out.println("done");
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

