【问题标题】:java split string[] array to multiple filesjava将字符串[]数组拆分为多个文件
【发布时间】:2012-07-05 10:42:05
【问题描述】:

我在弄清楚如何将字符串拆分为多个文件时遇到问题。目前我应该得到两个包含 JSON 数据的文件。下面的代码写入第一个文件,但第二个为空。任何想法为什么?

public void splitFile(List<String> results) throws IOException {

  int name = 0;
  for (int i=0; i<results.size(); i ++) {

    write = new FileWriter("/home/tom/files/"+ name +".json");
    out = new BufferedWriter(write);
    out.write(results.get(i));

    if (results.get(i).startsWith("}")) {
      name++;
    }      
  } 
}

编辑:它在以{ 开头的行拆分,因为那表示 JSON 文档的结尾。

【问题讨论】:

  • 你在哪里用close()关闭文件?如果您一次编写所有内容,则不需要 BufferedWriter。将write 设为循环内的局部变量。
  • 代码被破坏,因为它试图在迭代中重新打开同一个文件。另外,完成后关闭流。将write 移出循环并在if 语句中关闭当前文件并打开下一个文件。

标签: java json string file


【解决方案1】:

增强剪切控制

把这个放在一起:

write = new FileWriter("/home/tom/files/"+ name +".json");
out = new BufferedWriter(write);

还有这个:

name++;

检查开始,而不是结束

检查以{ 开头的行,并执行这三行打开文件。

记得关闭并冲洗

如果它不是第一行 (i &gt; 0),则关闭最后一个作者 (write.close();)。

关闭最后打开的写入器

if (!results.isEmpty())
    out.close();

结果

它应该看起来像这样:

public void splitFile(List<String> results) throws IOException {

  int name = 0;

  BufferedWriter out = null;
  for (int i=0; i<results.size(); i ++) {
    String line = results.get(i);
    if (line.startsWith("{")) {
       if (out != null) // it's not the first
          out.close(); // tell buffered it's going to close, it makes it flush
       FileWriter writer = new FileWriter("/home/tom/files/"+ name +".json");
       out = new BufferedWriter(writer);
       name++;
    }
    if (out == null)
       throw new IllegalArgumentException("first line doesn't start with {");
    out.write(line);
  } 

  if (out != null) // there was at least one file
     out.close();
}

【讨论】:

  • 如果您在第一次迭代中获得 {,这将失败。没试过,但我敢打赌它甚至没有编译(“out 可能没有被初始化”)。
  • 这与我正在使用的测试文件完美配合。出来并在类中写入并声明“私有静态”,以便对其进行初始化。谢谢=)
  • 我想你想说“如果你在第一次迭代中没有得到 { 将会失败”。当然。我不确定编译错误。我在这里写的,没试过。但这只是表明所有建议的外观。我会更正未初始化的。
  • 谢谢@Schmooo。请考虑我对它们所做的 cmets 和修改(签出 != null,首先使用“{”进行检查,等等)
  • 还有一件事。初始化的意思是“有一个赋值,甚至是空的”。如果您只声明没有= ... 部分的变量,则会在编译时引发警告/错误。另一个非常重要的事情:为什么你需要它私有静态?你只需要它私有的方法。如果它是一个字段或静态字段,它可能会从之前的执行中被初始化,并且检查(如out != null)会引发不正确的行为。
【解决方案2】:

我会在每个完成的写入序列后关闭您的缓冲写入器。即在每次循环迭代之后,然后将write 分配给新的FileWriter()

关闭BufferedWriter 将关闭底层FileWriter,并随后强制刷新写入磁盘的数据

注意:如果您在每个循环中使用不同的 FileWriter,那么我会将该变量的范围限定为该内部循环,例如

FileWriter write = new FileWriter("/home/tom/files/"+ name +".json");

BufferedWriter 也是如此。其实你可以写:

BufferedWriter outer = new BufferedWriter(new FileWriter(...

只处理outer

【讨论】:

  • 问题是 Schmooo 想在同一个文件中写入几行(多次循环迭代)。这就是为什么在循环结束时会检查以查找最外层 JSON 对象关闭的原因。
【解决方案3】:

试试下面的代码..

    public void splitFile(List<String> results) throws IOException {

    int name = 0;
    for (int i = 0; i < results.size(); i++) {

        write = new FileWriter("/home/tom/files/" + name + ".json");
        out = new BufferedWriter(write);
        out.write(results.get(i));
        out.flush();
        out.close();  // you have to close your stream every time in your case.

        if (results.get(i).startsWith("}")) {
            name++;
        }
    }
}

【讨论】:

  • 这将践踏上一次迭代中创建的文件的内容。
  • 我认为结果是行,有些行放在同一个文件中(这就是为什么名称只有在找到} 时才会增加)。
  • 这确实践踏了内容,无论如何要解决这个问题?使用 StringBuilder 然后将其内容写入文件会更好吗?
  • Schmoo,如果您只在name++ 之后每次都重新分配write,那将会有所帮助。当然,在重新分配之前,您需要关闭旧文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-28
相关资源
最近更新 更多