【问题标题】:Error or exceptions saving a .txt file (Java)保存 .txt 文件时出现错误或异常 (Java)
【发布时间】:2016-06-22 13:07:43
【问题描述】:

我在一个更大的循环中运行以下处理 (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];
}

【问题讨论】:

  • 你关闭你的作家了吗?
  • 使用 log4j 和 RollingFileAppender 怎么样?不过可能会慢一些。
  • 我只是改变了我的问题,我添加了整个代码
  • 除非我写 Java 代码已经有一段时间了,否则这不可能是“完整代码”,因为没有 class 声明。
  • 这是一个处理代码,似乎是基于 Java 的.....然而这是我正在运行的整个代码

标签: java file exception-handling processing stringbuilder


【解决方案1】:

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

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,表明重命名成功。然后查看草图文件夹,你会看到两个文本文件:one.txt 包含XYZtwo.txt 包含ABC这不是我们所期望的,这也是您的代码中正在发生的事情。

那么,发生了什么是这样的:

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

Java APIFile#renameTo() 函数,强调我的:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2019-07-28
    • 2013-03-13
    • 2015-04-01
    • 1970-01-01
    • 2013-07-04
    • 2016-07-02
    • 2013-08-15
    • 1970-01-01
    • 2016-01-20
    相关资源
    最近更新 更多