保存.txt文件的错误或异常(Java)

时间:2016-06-22 13:07:44

标签: java file exception-handling processing stringbuilder

我在更大的循环中运行以下处理(Java)代码。这些行将字符串保存在名为kinectDEM.tmp的.txt文件中,在此之前,旧文件重命名为kinectDEM1.txt,新文件(kinectDEM.tmp)重命名为kinectDEM0.txt }。

它工作正常但有时会卡住并且kinectDEM1.txt文件消失,代码仍然可以工作但不保存.txt文件。没有出现错误消息。 以这种方式保存.txt文件有什么问题吗?

以下是代码:

import java.io.File;
import SimpleOpenNI.*;
import java.util.*;
SimpleOpenNI kinect;
List<int[]> previousKinectValues = new LinkedList<int[]>();
int numPreviousToConsider = 60;
void setup()
{
  size(640, 480);
  kinect = new SimpleOpenNI(this);
  kinect.enableDepth();
  frameRate(60);
}
int precedente = millis();
void draw()
{
  kinect.update();
  PImage depthImage = kinect.depthImage();
  image(depthImage, 0, 0);
  int[] newDepthValues = kinect.depthMap();

  previousKinectValues.add(newDepthValues);
  if (previousKinectValues.size() > numPreviousToConsider) {
    previousKinectValues.remove(0);
  }
  int[] depthValues = average(previousKinectValues);
  depthValues = reverse(depthValues);
  StringBuilder sb = new StringBuilder();
  Deque<Integer> row = new LinkedList<Integer>();
  int kinectheight = 770; // kinect distance from the baselevel [mm]
  int scaleFactor = 1;
  int pixelsPerRow = 640;
  int pixelsToSkip = 40;
  int rowNum = 0;
  for (int i = 0; i < depthValues.length; i++) {
    if (i > 0 && i == (rowNum + 1) * pixelsPerRow) {
      fillStringBuilder(sb, row);
      rowNum++;
      sb.append("\n");
      row = new LinkedList<Integer>();
    }
    if (i < ((rowNum+1) * pixelsPerRow) - pixelsToSkip) {
    //if (i >= (rowNum * pixelsPerRow) + pixelsToSkip) {
      row.addFirst((kinectheight - depthValues[i]) * scaleFactor);
    }
  }
  fillStringBuilder(sb, row);
  String kinectDEM = sb.toString();
  final String[] txt= new String[1]; //creates a string array of 2 elements
  int savingtimestep = 2000;  // time step in millisec between each saving
  if (millis() > precedente + savingtimestep) {
    txt[0] = "ncols         600\nnrows         480\nxllcorner     0\nyllcorner     0\ncellsize      1\nNODATA_value  10\n" +kinectDEM;
    saveStrings("kinectDEM0.tmp", txt);
    precedente = millis();
    //  delete the old .txt file, from kinectDEM1 to kinectDEMtrash
    File f = new File(sketchPath("kinectDEM1.txt"));
    boolean success = f.delete();

    //  rename the old .txt file, from kinectDEM0 to kinectDEM1
    File oldName1 = new File(sketchPath("kinectDEM0.txt"));
    File newName1 = new File(sketchPath("kinectDEM1.txt"));
    oldName1.renameTo(newName1);
    //  rename kinectDEM0.tmp file to kinectDEM0.txt
    File oldName2 = new File(sketchPath("kinectDEM0.tmp"));
    File newName2 = new File(sketchPath("kinectDEM0.txt"));
    oldName2.renameTo(newName2);

  }
}
void fillStringBuilder(StringBuilder sb, Deque<Integer> row) {
  boolean emptyRow = false;
  while (!emptyRow) {
    Integer val = row.pollFirst();
    if (val == null) {
      emptyRow = true;
    } else {
      sb.append(val);
      val = row.peekFirst();
      if (val != null) {
        sb.append(" ");
      }
    }
  }
}
int[] average(List<int[]> previousKinectValues) {
  if (previousKinectValues.size() > 0) {
    int[] first = previousKinectValues.get(0);
    int[] avg = new int[first.length];
    for (int[] prev : previousKinectValues) {
      for (int i = 0; i < prev.length; i++) {
        avg[i] += prev[i];
      }
    }
    int num = previousKinectValues.size();
    for (int i = 0; i < avg.length; i++) {
        avg[i] /= num;
    }
    return avg;
  }
  return new int[0];
}

1 个答案:

答案 0 :(得分:0)

您可以将问题简化为更小的示例草图:

saveStrings("one.txt", new String[]{"ABC"});
File oldName = new File(sketchPath("one.txt"));
File newName = new File(sketchPath("two.txt"));
boolean renamed = oldName.renameTo(newName);
println(renamed);

将来,请尝试将您的问题缩小到这样的MCVE

无论如何,此程序将文本ABC保存到名为one.txt的文件中。然后,它会尝试将one.txt重命名为two.txt。这正是您尝试做的,只是没有额外的kinect代码,这与您的问题没有任何关系。

请运行此小示例程序,然后查看草图目录(草图&gt;显示草图文件夹)。您将看到two.txt文件,该文件将在一行中包含文本ABC。另请注意,程序会将true打印到控制台,指示重命名已成功。这正是您所期望的。

现在,将第一行更改为:

saveStrings("one.txt", new String[]{"XYZ"});

再次运行程序。首先注意它打印出false到控制台,表明重命名成功。然后查看草图文件夹,您将看到两个文本文件:one.txt包含XYZtwo.txt,其中包含ABC这不是我们所期望的,这也是您的代码中发生的事情。

所以,发生了什么:

我们运行代码,创建包含one.txt的{​​{1}},然后将其重命名为ABC。然后,我们再次运行代码,创建包含two.txt的{​​{1}}。然后,我们尝试将该新文件重命名为one.txt,但我们无法

XYZ函数的Java API开始,强调我的:

  

此方法行为的许多方面本质上都依赖于平台:重命名操作可能无法将文件从一个文件系统移动到另一个文件系统,它可能不是原子的,而如果是目标抽象路径名的文件已存在。应始终检查返回值以确保重命名操作成功。

     

请注意,Files类定义了以独立于平台的方式移动或重命名文件的移动方法。

因此看起来重命名步骤失败了,因为您无法重命名文件以覆盖现有文件。相反,我们可以使用Files#move()函数,它允许我们指定覆盖选项:

two.txt