好吧,我設法得到的地方 - 但我還是想更合格的答案。
首先,事實證明,加工爲這樣的期望要被讀取的文件(如在OP示例myprops.properties
),將被存儲在一個data
子目錄草圖文件夾:
https://processing.org/tutorials/data/
就像圖像文件一樣,這些文本文件應放置在草圖的「數據」目錄中,以便它們被Processing草圖識別。
到目前爲止好 - 事實上,在處理.pde
草圖裏面,我們可以使用(比方說)loadStrings("myprops.properties");
,在data/myprops.properties
文件將被讀取。但是,我不需要在那裏讀取文件 - 我需要在支持.java
的課程中閱讀它。
現在,當您運行Processing修補程序(無論是從IDE還是從命令行),會發生什麼情況是Processing會將源文件從sketch文件夾複製到/tmp
文件夾中的臨時文件夾中(至少在Linux的);以下是文件結構的樣子:
/tmp/testprocjavapath9179591342074530534temp/
├── MyJavaClass.class
├── source
│ ├── MyJavaClass.java
│ └── testprocjavapath.java
└── testprocjavapath.class
注意到我們.java
源文件,並.class
「編譯」的文件,但沒有data
子文件夾或文件myprops.properties
任何地方!
現在,請注意,源素描文件夾中曾經是testprocjavapath.pde
的東西在臨時文件夾中變成testprocjavapath.java
(和相應的.class
);注意到testprocjavapath.java
定義:
public class testprocjavapath extends PApplet {
現在,loadStrings
實際上是PApplet
類的方法;所以,如果我們通讀了一下:
https://github.com/processing/processing/blob/master/core/src/processing/core/PApplet.java
dataPath(String where)
:....數據路徑不同的方式處理每一個平臺上,而不應被視爲一個位置寫入文件。也不應該假定這個位置可以被讀取或列出。 ...庫應該使用createInput()來獲取InputStream或createOutput()來獲取OutputStream。 sketchPath()可用於獲取相對於草圖的位置。再次,不要使用此來獲取文件的相對位置。 ...
...我們可以看到一種方法dataPath
,但不推薦使用它。另一方面,有一個方法sketchPath
- 但是,這種方法將只有返回正確的路徑(即在此示例~/sketchbook
草圖)如果從頂級.pde
文件調用!如果您嘗試將.java
文件中的類定義爲extends PApplet
,然後從那裏調用sketchPath
- 它將僅返回當前工作目錄!
所以現在的解決方案是:
下面一個改變testProcJavaLoadpath.sh
粘貼,具有這些修改,原則,工作 - 這是終端輸出:
$ bash testProcJavaLoadpath.sh
...
Sketch first lines: 'teststr=HelloWorld';
Sketch dataFile: '~/sketchbook/testprocjavapath/data/myprops.properties';
Sketch sketchPath: '~/sketchbook/testprocjavapath';
:: mySketchPath: '~/sketchbook/testprocjavapath'
:: The URL is 'file:/tmp/testprocjavapath4709659129218148940temp/';
:: name: MyJavaClass.class
:: resourcePath: file:/tmp/testprocjavapath4709659129218148940temp/MyJavaClass.class
:: theFilePath: '~/sketchbook/testprocjavapath/data/myprops.properties'
:: properties: key 'teststr' => value 'HelloWorld'
The properties file content is 'teststr=HelloWorld
';
...但是,我想,如果我想將此代碼打包到.jar
或可執行應用程序/文件中,這種方法可能會失敗 - 這就是爲什麼我仍然想要更合適的答案。
的改變testProcJavaLoadpath.sh
是這樣的:
PROCSKETCHDIR="~/sketchbook"
PROCSKETCHDIR="${PROCSKETCHDIR/#\~/$HOME}" # expand home dir ~
echo "$PROCSKETCHDIR"
PROCBINPATH="/PATH/TO/processing-3.3.6" # path/location of Processing executable `processing-java`
MYSKETCH="testprocjavapath"
MYSKETCHDIR="$PROCSKETCHDIR/$MYSKETCH"
# reconstruct folder:
rm -rfv "$MYSKETCHDIR"
mkdir -v "$MYSKETCHDIR"
# https://processing.org/tutorials/data/
# "And just as with image files, these text files should be placed in the sketch’s 「data」 directory in order for them to be recognized by the Processing sketch."
# processing.core.PApplet.loadStrings - https://processing.github.io/processing-javadocs/core/
# https://github.com/processing/processing/blob/master/core/src/processing/core/PApplet.java
# "dataPath(String where): The data path is handled differently on each platform, and should not be considered a location to write files. It should also not be assumed that this location can be read from or listed. ... Libraries should use createInput() to get an InputStream or createOutput() to get an OutputStream. sketchPath() can be used to get a location relative to the sketch. Again, <b>do not</b> use this to get relative locations of files."
echo "generating $MYSKETCHDIR/$MYSKETCH.pde"
cat > "$MYSKETCHDIR/$MYSKETCH.pde" <<'EOF'
void setup() {
size(640, 360); // Size should be the first statement
String[] lines = loadStrings("myprops.properties"); // reads from data/myprops.properties
System.out.format("Sketch first lines: '%s';%n", lines[0]);
System.out.format("Sketch dataFile: '%s';%n", dataFile("myprops.properties")); // ~/sketchbook/testprocjavapath/data/myprops.properties
System.out.format("Sketch sketchPath: '%s';%n", sketchPath()); // ~/sketchbook/testprocjavapath
MyJavaClass myjc = new MyJavaClass(sketchPath());
String thefilecontents = myjc.GetPropsFileContent();
System.out.format("The properties file content is '%s';%n", thefilecontents);
}
EOF
mkdir -v "$MYSKETCHDIR/data"
echo "generating $MYSKETCHDIR/data/myprops.properties"
cat > "$MYSKETCHDIR/data/myprops.properties" <<'EOF'
teststr=HelloWorld
EOF
echo "generating $MYSKETCHDIR/MyJavaClass.java"
cat > "$MYSKETCHDIR/MyJavaClass.java" <<'EOF'
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream; // "InputStream is by definition not seekable."
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.io.FileInputStream; // is seekable
import java.io.File;
import java.io.ByteArrayOutputStream;
import java.net.URL;
//import processing.core.*;
import java.nio.file.Path;
import java.nio.file.Paths;
public class MyJavaClass {
private static final String PROPERTIES_FILENAME = "myprops.properties";
public String mySketchPath;
/**
* add a constructor
*/
public MyJavaClass(String inSketchPath) {
mySketchPath = inSketchPath;
}
public String GetPropsFileContent() {
//System.out.format(":: sketchPath: '%s'%n", sketchPath()); // if `MyJavaClass extends PApplet`, then sketchPath() just prints current working directory!
System.out.format(":: mySketchPath: '%s'%n", mySketchPath);
getLocations();
String myret = null;
myret = readgetFileContent(PROPERTIES_FILENAME);
return myret;
}
public String readgetFileContent(String inFileName) {
String result = null;
Properties properties = new Properties();
try {
//String theFilePath = inFileName; // verbatim relative path fails
Path inFileNameSketchPath = Paths.get(mySketchPath, "data", inFileName); // OS path join
String theFilePath = inFileNameSketchPath.toString();
System.out.format(":: theFilePath: '%s'%n", theFilePath);
//InputStream in = MyJavaClass.class.getResourceAsStream(theFilePath); // no can do, is 'null', also w/ abs path
//InputStream in = new FileInputStream(new File(theFilePath)); // OK, but not seekable
FileInputStream in = new FileInputStream(new File(theFilePath));
properties.load(in);
// double-check loaded properties:
for(String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
System.out.format(":: properties: key '%s' => value '%s'%n", key, value);
}
ByteArrayOutputStream resultbaos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
in.getChannel().position(0); // do reset - seek 0 (start), to reset stream again for reading
while ((length = in.read(buffer)) != -1) {
resultbaos.write(buffer, 0, length);
}
result = resultbaos.toString();
} catch (IOException e) {
System.err.println("There was an error reading " + inFileName + ": " + e.getCause()
+ " : " + e.getMessage());
} catch (Exception e) {
System.err.println("There was an exception " + inFileName + ": " + e
+ " : " + e.getMessage());
}
return result;
}
public void getLocations() {
URL classURL = getClass().getProtectionDomain().getCodeSource().getLocation();
System.out.format(":: The URL is '%s';%n", classURL); // file:/tmp/testprocjavapath3056820301028631180temp/
String s = getClass().getName();
int i = s.lastIndexOf(".");
if(i > -1) s = s.substring(i + 1);
s = s + ".class";
System.out.println(":: name: " + s);
Object resourcePath = this.getClass().getResource(s);
System.out.println(":: resourcePath: " + resourcePath); // file:/tmp/testprocjavapath9185318125154993853temp/MyJavaClass.class
}
}
EOF
# run once:
"$PROCBINPATH"/processing-java --sketch="$MYSKETCHDIR" --run
我很困惑你想要做什麼。你可能會嘗試發佈一個更小的[mcve]?就像'println(new File(「test.txt」)。getAbsolutePath())'一樣簡單,可以幫助您理解您期望發生的事情與實際發生的事情。另外,你如何編譯和運行它? –