我正在使用runtime.exec尝试将一个. SQL脚本执行到我本地的SQLite数据库文件中。我目前正在MacOS上运行这个。
Runtime runtime = Runtime.getRuntime();
try
{
Process process = runtime.exec("sqlite3 /Users/Documents/Uni/Music\\ Player/src/Common/database.db < /Users/Documents/Uni/Music\\ Player/src/Common/database.sql");
BufferedReader stdError = new BufferedReader(newInputStreamReader(process.getErrorStream()));
try {
if (process.waitFor() != 0) {
String s = "";
System.err.println("exit value = " + process.exitValue());
System.out.println("Here is the standard error of the command (if any):");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
}
} catch (InterruptedException e) {
System.err.println(e);
}
这是我当前使用的代码。如果我通过终端执行命令,它将成功执行,我的数据库将用.SQL脚本的内容更新。
然而,当我通过代码执行此操作时,我会得到错误:
错误:“Player”附近:语法错误
以及进程退出
我一辈子都找不到字符串语法有什么问题。我尝试了多种不同的方法来转义字符串中的空格,但没有成功。有什么想法吗?
匿名用户
如果您查看“Runtime.exec()的文档,并遵循实用程序方法的扩展,您将会看到:
更准确地说,使用由调用new StringTokenizer(命令)创建的StringTokenizer将命令字符串分解为标记,而不需要进一步修改字符类别
现在,如果您尝试使用< code>StringTokenizer单独断开字符串,您会看到它被分成:
sqlite3
/Users/Documents/Uni/Music\
Player/src/Common/database.db
<
/Users/Documents/Uni/Music\
Player/src/Common/database.sql
与其将整个命令传递给exec
,不如使用接受命令及其参数为字符串[]
的exec版本:
runtime.exec(new String[]{
"sqlite3",
" /Users/Documents/Uni/Music Player/src/Common/database.db"
});
然而,像这样阅读输入是行不通的。当您键入命令时,shell会对其进行解释。除了< code>exec之外,您可能希望使用< code>Process,如使用来自Java的重定向标准输入和标准输出运行外部程序中所示。
让我们创建一个< code>Path并让它为您生成文件路径,而不是尝试使用手动硬编码的< code>String来生成文件路径。这很容易使用,而且无论操作系统或文件系统是什么,都可以生成正确的文件路径。
将当前的exec命令替换为this以实现该更改:
Path parentDirectory = Paths.get("Users","Documents","Uni","Music Player","src","Common");
String sqlCommand = "sqlite3 database.db < database.sql";
Process process = runtime.exec(sqlCommand, null, parentDirectory.toFile());
这将运行“sqlite3数据库.db
但是,尽管修复了原始问题,但您的代码还包含与使用文件重定向相关的另一个问题。文件重定向方式
下面是修复了这两个问题的代码:
Path parentDirectory = Paths.get("Users","Documents","Uni","Music Player","src","Common");
String sqlCommand = "sqlite3 database.db";
File inputSqlFile = new File("database.sql");
Process process = new ProcessBuilder()
.directory(parentDirectory.toFile())
.command(sqlCommand)
.redirectInput(Redirect.from(inputSqlFile))
.start();
此代码使用
ProcessBuilder
将目录设置为与以前相同的父目录,但该命令已修改为删除文件重定向,而是使用 redirectinput()
方法实现文件重定向。这与“sqlite3 数据库”完成相同的操作.db
编辑:
上面的代码不起作用,所以我试图修复它,并添加了调试语句来帮助跟踪问题:
Path databasePath = FileSystems.getDefault().getPath("Users", "Documents", "Uni", "Music Player", "src", "Common", "database.db");
Path sqlPath = FileSystems.getDefault().getPath("Users", "Documents", "Uni", "Music Player", "src", "Common", "database.sql");
File database = databasePath.toFile().getAbsoluteFile();
File sqlFile = sqlPath.toFile().getAbsoluteFile();
System.out.println("Database location:\n\t" + database.getCanonicalPath());
System.out.println("SQL file location:\n\t" + sqlFile.getCanonicalPath());
assert database.exists() && database.isFile() && database.canRead() && database.canWrite(): "No such database file!";
assert sqlFile.exists() && sqlFile.isFile() && database.canRead() : "No such SQL file!";
String[] sqlCommand = {"sqlite3", database.getCanonicalPath()};
Redirect sqlInput = Redirect.from(sqlFile);
File workingDirectory = database.getParentFile().getCanonicalFile();
System.out.println("Running this command:\n\t" +
sqlCommand[0] + sqlCommand[1] + "<" + sqlInput.file().getCanonicalPath());
Process process = new ProcessBuilder()
.directory(workingDirectory)
.command(sqlCommand)
.redirectInput(sqlInput)
.start();
这是相同的代码,删除了调试代码并进行了轻微清理:
File database = FileSystems.getDefault()
.getPath("Users", "Documents", "Uni","Music Player", "src", "Common", "database.db")
.toFile().getAbsoluteFile();
File sqlFile = FileSystems.getDefault()
.getPath("Users", "Documents", "Uni","Music Player", "src", "Common", "database.sql")
.toFile().getAbsoluteFile();
String[] sqlCommand = {"sqlite3", database.getCanonicalPath()};
Redirect sqlInput = Redirect.from(sqlFile);
File workingDirectory = database.getParentFile().getCanonicalFile();
Process process = new ProcessBuilder()
.directory(workingDirectory)
.command(sqlCommand)
.redirectInput(sqlInput)
.start();
有人能告诉我这个: 在第二行,我得到一个错误。但这行得通: 我需要更多的文字后,我打印的名称。有人知道怎么做吗?
通常我不会在这里发布语法错误,但这个案例对我来说有点可疑。我试图用一个字符串组合一个常数。我在本地主机上工作正常,但当我在web服务器上推送项目时,它会告诉我: 代码: 和 这与不同的PHP版本有关吗?(5.5在网络服务器,7.0localhost) 最新消息 代码中的一些更新:
我有一个XML字符串,如下所示: 现在,我用名称数据将其解组到类中。java,它将变量作为CustomerInfo的另一个类。JAVA 但在解组时,我得到了一个错误作为意外元素(uri:)https://www.google/com,本地:“数据”)。预期的元素为
我正在尝试运行基本的hello-world应用程序。我完全沮丧,找不到解决这个问题的办法。怎么了?我已经尝试了这些解决方案,但仍然没有运气。请帮助我:'(
谁能告诉我这个密码是什么?我尝试了所有方法,但不知道为什么它总是给我这个错误: 第3行出现解析错误:...","简称":"简单","长" - 应为“STRING”、“NUMBER”、“NULL”、“TRUE”、“FALSE”、“{”和“[” 谢谢
问题内容: 我正在制作基于文本的骰子滚轴。它接受“ 2d10 + 5”之类的字符串,并作为滚动结果返回一个字符串。我的问题出现在令牌生成器中,该令牌生成器将字符串拆分为有用的部分,以便我解析为信息。 这会产生奇怪的意外结果。我不知道是什么原因造成的。可能是正则表达式,我的误解,或者Java只是Java。这是正在发生的事情: 产生字符串数组。这是对的。 产生字符串数组。这是对的。 产生字符串数组。这