关闭并重新启动可执行文件后,无法修改或删除由我的 .jar 可执行文件创建的文本文件
Unable to modify or delete text file created by my .jar executable after closing and relaunching the executable
我有一个相当简单的 Java 项目,它打开(如果不存在则创建)当前目录(我的 [=31 中某处)中的文本文件=]Documents文件夹),用BufferedReader读取数据,然后用PrintWriter修改。该代码在 Eclipse 中运行良好。但是当导出到 运行nable .jar 文件时,生成的 .jar 可执行文件只能修改它自己创建的文件(创建是因为它之前不存在)。如果我然后关闭并重新启动 .jar 作为新实例来修改它上次启动时创建的文件,我得到
java.io.FileNotFoundException: Data.txt (Access is denied)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:293)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:184)
at java.base/java.io.PrintWriter.<init>(PrintWriter.java:309)
at project.file.LocalStorageFile.setList(LocalStorageFile.java:136)
...
所以重申一下:
- 运行 在 eclipse 中 - 工作正常
- 导出到运行可用的 jar
- 运行罐子
- 如果文件不存在则创建一个
- 读取文件
- 如果它在第 4 步中创建了文件 - 写入成功,但如果文件已经存在 - 异常
在调查此异常时,答案建议:
- C 盘上的受限目录(这对我来说不是,因为我的是 Documents 中的一个完全可访问(至少一次)的文件夹,并且该文件夹的权限似乎是有序的)
- 忘记关闭流(我在 finally 块中关闭了 reader 和 writer 流,并确保它们已通过一些控制台打印行关闭)
- 文件正在被使用(计算机重启后问题仍然存在,甚至在我之前不得不重新安装 OS 之后)
- 缺乏管理员权限(我以管理员身份启动了 CMD 并将其用于“java -jar project.jar”,结果相同)
- 尝试使用等于 falsefile.delete() 删除文件
- 尝试冲洗打印机
- 尝试使用 file.setReadable(true) 和 file.setWritable(true)
将文件设置为可读和可写
我正在使用 gradle 构建我的 .jar,因为我需要一些从那里获取的库来实现其他功能。但即使我使用 Eclipse 本身“导出为 运行nable jar”,我也会遇到同样的问题。当然,当我多次直接从 Eclipse 运行 程序时,访问和修改同一个文件没有问题。
这是我的 LocalStorageFile class,如果你想在你的机器上测试它,它具有读写功能:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.TreeMap;
/**
* Store keywords and strings in a local file.
*
* Format: keyword1, keyword2 \t string1 \n keyword3, keyword4 \t string2
* \n
*/
public class LocalStorageFile {
private static final String FILE_PATH = "Data.txt"; // current directory
private static final String KEY_SEP = "\t"; // key/value separator
private static final String LINE_SEP = "\n"; // line separator
private static File file;
public LocalStorageFile() {
file = new File(FILE_PATH);
// Create file if it doesn't exist
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Retrieve list from file "Data.txt" in local directory.
*
* @return TreeMap of keys and strings.
*/
public static TreeMap<String, String> getList() {
System.out.println("Retrieving list data.");
TreeMap<String, String> myList = new TreeMap<String, String>();
File file = new File(FILE_PATH);
if (!file.exists()) {
try {
file.createNewFile(); // if file already exists will do nothing
} catch (IOException e1) {
e1.printStackTrace();
}
}
BufferedReader br = null;
// Read file line by line and add to myList
try {
file.setReadable(true);
file.setWritable(true);
br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
System.out.println(" Now reading line:" + line);
String[] keyValuePair = line.split(KEY_SEP);
if (keyValuePair.length == 2) { // avoid any error lines
// Re-insert tabs and newlines
String key = keyValuePair[0].replaceAll("\\t", "\t")
.replaceAll("\\n", "\n");
String value = keyValuePair[1].replaceAll("\\t", "\t")
.replaceAll("\\n", "\n");
// Put data into map
myList.put(key, value);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
System.out.println("Buffered reader closed.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return myList;
}
/**
* Rewrite list to file "Data.txt" in local directory.
*
* @param myList
* TreeMap of keys and strings.
* @return 1 on success, 0 on fail.
*/
public static int setList(TreeMap<String, String> myList) {
System.out.println("Saving list data.");
String textData = "";
int result = 0;
// Construct textData using myList
for (String key : myList.keySet()) {
String value = myList.get(key);
// Sanitize strings
String keyClean = key.replaceAll("\t", "\\t").replaceAll("\n",
"\\n");
String valueClean = value.replaceAll("\t", "\\t").replaceAll(
"\n", "\\n");
// Assemble line with separators
String line = keyClean + KEY_SEP + valueClean + LINE_SEP;
System.out.println(" Now saving line:" + line);
textData += line;
}
// Replace file content with textData
PrintWriter prw = null;
File file = new File(FILE_PATH);
if (file.exists()) {
boolean delStatus = file.delete();
System.out.println("File deleted? " + delStatus);
// file.setReadable(true);
// file.setWritable(true);
} else {
System.out.println("File doesn't exist");
}
try {
file.createNewFile();
prw = new PrintWriter(file); // <- this is line 136 from the exception
prw.println(textData);
prw.flush();
result = 1;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (prw != null) {
prw.close();
System.out.println("Print writer closed.");
}
}
return result;
}
}
这似乎不是代码的问题,但也许我的系统有问题?
任何关于我应该在哪里挖掘的线索都将不胜感激。
好的。我终于开始工作了。我不得不暂时关闭我的 Avast Antivirus 并且我能够编辑现有文件。特别是“勒索软件保护”正在保护我的文档文件夹。
谢谢各位评论者的帮助,没有你们我不可能得出这个结论! 中的一个答案提到了导致同样问题的 Comodo 杀毒软件。我将在未受保护的文件夹中创建一个新的工作目录,因为 Avast 不允许我作为例外添加非 exe 文件。
我有一个相当简单的 Java 项目,它打开(如果不存在则创建)当前目录(我的 [=31 中某处)中的文本文件=]Documents文件夹),用BufferedReader读取数据,然后用PrintWriter修改。该代码在 Eclipse 中运行良好。但是当导出到 运行nable .jar 文件时,生成的 .jar 可执行文件只能修改它自己创建的文件(创建是因为它之前不存在)。如果我然后关闭并重新启动 .jar 作为新实例来修改它上次启动时创建的文件,我得到
java.io.FileNotFoundException: Data.txt (Access is denied) at java.base/java.io.FileOutputStream.open0(Native Method) at java.base/java.io.FileOutputStream.open(FileOutputStream.java:293) at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:235) at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:184) at java.base/java.io.PrintWriter.<init>(PrintWriter.java:309) at project.file.LocalStorageFile.setList(LocalStorageFile.java:136) ...
所以重申一下:
- 运行 在 eclipse 中 - 工作正常
- 导出到运行可用的 jar
- 运行罐子
- 如果文件不存在则创建一个
- 读取文件
- 如果它在第 4 步中创建了文件 - 写入成功,但如果文件已经存在 - 异常
在调查此异常时,答案建议:
- C 盘上的受限目录(这对我来说不是,因为我的是 Documents 中的一个完全可访问(至少一次)的文件夹,并且该文件夹的权限似乎是有序的)
- 忘记关闭流(我在 finally 块中关闭了 reader 和 writer 流,并确保它们已通过一些控制台打印行关闭)
- 文件正在被使用(计算机重启后问题仍然存在,甚至在我之前不得不重新安装 OS 之后)
- 缺乏管理员权限(我以管理员身份启动了 CMD 并将其用于“java -jar project.jar”,结果相同)
- 尝试使用等于 falsefile.delete() 删除文件
- 尝试冲洗打印机
- 尝试使用 file.setReadable(true) 和 file.setWritable(true) 将文件设置为可读和可写
我正在使用 gradle 构建我的 .jar,因为我需要一些从那里获取的库来实现其他功能。但即使我使用 Eclipse 本身“导出为 运行nable jar”,我也会遇到同样的问题。当然,当我多次直接从 Eclipse 运行 程序时,访问和修改同一个文件没有问题。
这是我的 LocalStorageFile class,如果你想在你的机器上测试它,它具有读写功能:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.TreeMap;
/**
* Store keywords and strings in a local file.
*
* Format: keyword1, keyword2 \t string1 \n keyword3, keyword4 \t string2
* \n
*/
public class LocalStorageFile {
private static final String FILE_PATH = "Data.txt"; // current directory
private static final String KEY_SEP = "\t"; // key/value separator
private static final String LINE_SEP = "\n"; // line separator
private static File file;
public LocalStorageFile() {
file = new File(FILE_PATH);
// Create file if it doesn't exist
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Retrieve list from file "Data.txt" in local directory.
*
* @return TreeMap of keys and strings.
*/
public static TreeMap<String, String> getList() {
System.out.println("Retrieving list data.");
TreeMap<String, String> myList = new TreeMap<String, String>();
File file = new File(FILE_PATH);
if (!file.exists()) {
try {
file.createNewFile(); // if file already exists will do nothing
} catch (IOException e1) {
e1.printStackTrace();
}
}
BufferedReader br = null;
// Read file line by line and add to myList
try {
file.setReadable(true);
file.setWritable(true);
br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
System.out.println(" Now reading line:" + line);
String[] keyValuePair = line.split(KEY_SEP);
if (keyValuePair.length == 2) { // avoid any error lines
// Re-insert tabs and newlines
String key = keyValuePair[0].replaceAll("\\t", "\t")
.replaceAll("\\n", "\n");
String value = keyValuePair[1].replaceAll("\\t", "\t")
.replaceAll("\\n", "\n");
// Put data into map
myList.put(key, value);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
System.out.println("Buffered reader closed.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
return myList;
}
/**
* Rewrite list to file "Data.txt" in local directory.
*
* @param myList
* TreeMap of keys and strings.
* @return 1 on success, 0 on fail.
*/
public static int setList(TreeMap<String, String> myList) {
System.out.println("Saving list data.");
String textData = "";
int result = 0;
// Construct textData using myList
for (String key : myList.keySet()) {
String value = myList.get(key);
// Sanitize strings
String keyClean = key.replaceAll("\t", "\\t").replaceAll("\n",
"\\n");
String valueClean = value.replaceAll("\t", "\\t").replaceAll(
"\n", "\\n");
// Assemble line with separators
String line = keyClean + KEY_SEP + valueClean + LINE_SEP;
System.out.println(" Now saving line:" + line);
textData += line;
}
// Replace file content with textData
PrintWriter prw = null;
File file = new File(FILE_PATH);
if (file.exists()) {
boolean delStatus = file.delete();
System.out.println("File deleted? " + delStatus);
// file.setReadable(true);
// file.setWritable(true);
} else {
System.out.println("File doesn't exist");
}
try {
file.createNewFile();
prw = new PrintWriter(file); // <- this is line 136 from the exception
prw.println(textData);
prw.flush();
result = 1;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (prw != null) {
prw.close();
System.out.println("Print writer closed.");
}
}
return result;
}
}
这似乎不是代码的问题,但也许我的系统有问题?
任何关于我应该在哪里挖掘的线索都将不胜感激。
好的。我终于开始工作了。我不得不暂时关闭我的 Avast Antivirus 并且我能够编辑现有文件。特别是“勒索软件保护”正在保护我的文档文件夹。
谢谢各位评论者的帮助,没有你们我不可能得出这个结论!