我在更大的循环中运行以下处理(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];
}
答案 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
包含XYZ
和two.txt
,其中包含ABC
。 这不是我们所期望的,这也是您的代码中发生的事情。
所以,发生了什么:
我们运行代码,创建包含one.txt
的{{1}},然后将其重命名为ABC
。然后,我们再次运行代码,创建包含two.txt
的{{1}}。然后,我们尝试将该新文件重命名为one.txt
,,但我们无法。
从XYZ
函数的Java API开始,强调我的:
此方法行为的许多方面本质上都依赖于平台:重命名操作可能无法将文件从一个文件系统移动到另一个文件系统,它可能不是原子的,而如果是目标抽象路径名的文件已存在。应始终检查返回值以确保重命名操作成功。
请注意,Files类定义了以独立于平台的方式移动或重命名文件的移动方法。
因此看起来重命名步骤失败了,因为您无法重命名文件以覆盖现有文件。相反,我们可以使用Files#move()
函数,它允许我们指定覆盖选项:
two.txt