java - 保存 .txt 文件时出现错误或异常 (Java)

标签 java file exception 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];
}

最佳答案

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

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 代码,这与您的问题没有任何关系。

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

现在,将第一行更改为:

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

再次运行该程序。首先请注意,它在控制台上打印出 false ,表明重命名成功。然后查看 sketch 文件夹,您将看到两个文本文件:包含 XYZone.txt 和包含 ABCtwo.txt这不是我们所期望的,这也是您的代码中发生的情况。

所以,发生的事情是这样的:

我们运行代码,创建包含 ABCone.txt,然后将其重命名为 two.txt。然后我们再次运行代码,创建包含 XYZone.txt。然后,我们尝试将该新文件重命名为 two.txt但我们不能

来自Java API对于 File#renameTo() 函数,强调我的:

Many aspects of the behavior of this method are inherently platform-dependent: The rename operation might not be able to move a file from one filesystem to another, it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists. The return value should always be checked to make sure that the rename operation was successful.

Note that the Files class defines the move method to move or rename a file in a platform independent manner.

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

Files.move(oldName.toPath(), newName.toPath(), StandardCopyOption.REPLACE_EXISTING);

关于java - 保存 .txt 文件时出现错误或异常 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37969003/

相关文章:

java - Morphia 在保存到 DataStore 时给出 NoSuchMethodError

java - 如何阻止 Eclipse 在每次捕获异常时中断?

php - php中openssl解密的异常处理

java - 如何隐藏 Android 中现有的文件夹?

asp.net - 如何从异常中获取更多详细信息?

java - Hibernate Validator - @Length - 如何为最小值和最大值指定单独的消息?

Java Tibco EMS 不使用 TibjmsAdmin 获取队列列表

java - java中如何临时标记对象

c++ - QTextStream 无法使用 openmode QIODevice::Append 写入包含 "\t"的文件

ios - 如何使用 Url 初始化 OutputStream?