英文:
How to write to a local file in a Java Dynamic WebService application?
问题
以下是我翻译好的内容:
/**
* 用于读取存储在 JSON 文件中数据的实用方法。
*
* @param filePath 所需数据库表的路径
* @return 所需表的内容
* @throws IOException 在找不到所需文件时抛出
*/
public static String readFile(String filePath) throws IOException {
InputStream inputStream = DBHelper.class.getResourceAsStream(filePath);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
return content;
}
/**
* 将新书添加到 Books.json 文件中
*/
public void postBook(Book book, String filePath) {
// 创建带有漂亮打印的 Gson 实例
Gson gson = new GsonBuilder().setPrettyPrinting().create();
// 首先,将 Book 对象转换为 Json 字符串
try {
File file = new File(filePath);
OutputStream out = new FileOutputStream(file);
// 此逻辑将检查文件是否存在。如果在指定位置找不到文件,它会创建一个新文件
if (!file.exists()) {
file.createNewFile();
}
List<Book> books;
String updatedBooksJson;
// 如果文件为空,只需将对象放入其中 - 不需要先前的逗号
if (DBHelper.tableIsEmpty(filePath)) {
books = new ArrayList<Book>();
books.add(book);
updatedBooksJson = gson.toJson(books);
// 写入文件
byte[] bytes = updatedBooksJson.getBytes();
out.write(bytes[6]);
out.flush();
} else {
// 文件不为空。读取当前文件中的产品列表,将其转换为 List<Book>,添加新的 Book,然后更新文件
books = getAllBooks(filePath);
// 将新书添加到现有书籍列表中:
books.add(book);
// 将更新后的书籍列表写入 Books.json 文件
updatedBooksJson = gson.toJson(books);
// 清空旧文件内容
FileChannel.open(Paths.get(filePath), StandardOpenOption.WRITE).truncate(0).close();
// 写入新的文件内容
byte[] bytes = updatedBooksJson.getBytes();
out.write(bytes[6]);
out.flush();
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
这是写入 /com/ebook/database/Books.json
文件时发生 FileNotFoundException
的问题。
英文:
I have a file that contains json data Books.json
. The file is located in package com.ebook.database
. I can successfully read the file's contents, but I when I try to write to the file, I get a FileNotFoundException
.
Below is my project's strudture, showing the package in which the Books.json
file is located:
Below is the code I use to successfully read the file's contents (filePath
receives a String value of /com/ebook/database/Books.json
and reads the file just fine:
/**
* A utility method for reading the data stored in a json file.
*
* @param filePath path to the desired database table
* @return the contents of the desired table
* @throws IOException occurs when the desired file is not found
*/
public static String readFile(String filePath) throws IOException {
InputStream inputStream = DBHelper.class.getResourceAsStream(filePath);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
return content;
}
Below is the code I'm using to try to access the same Books.json
file for writing, unsuccessfully:
/**
* Adds a new Book to the Books.json file
* */
public void postBook(Book book, String filePath) {
//create Gson instance with pretty-print
Gson gson = new GsonBuilder().setPrettyPrinting().create();
//First, convert the Product object into a Json string
try {
File file = new File(filePath);
OutputStream out = new FileOutputStream(file);
/* This logic will check whether the file
* exists or not. If the file is not found
* at the specified location it would create
* a new file*/
if (!file.exists()) {
file.createNewFile();
}
List<Book> books;
String updatedBooksJson;
//if file is empty, just throw the object in -- no prior comma needed.
if(DBHelper.tableIsEmpty(filePath)) {
books = new ArrayList<Book>();
books.add(book);
updatedBooksJson = gson.toJson(books);
//writing to the file.
byte[] bytes = updatedBooksJson.getBytes();
out.write(bytes[6]);
out.flush();
} else {
//The file is not empty. Read the list of Products currently
//in the file, convert to List<Product>, add the new Product, and
//update the file
books = getAllBooks(filePath);
//add the new product to the existing list of products:
books.add(book);
//write the updated products list to the Products.json file
updatedBooksJson = gson.toJson(books);
//clear the old file contents
FileChannel.open(Paths.get(filePath), StandardOpenOption.WRITE).truncate(0).close();
//write the new file contents
//writing to the file.
byte[] bytes = updatedBooksJson.getBytes();
out.write(bytes[6]);
out.flush();
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Below is the resulting stacktrace when attempting to write to the /com/ebook/database/Books.json
file:
INFO: Server startup in 2782 ms
java.io.FileNotFoundException: \com\ebook\database\Books.json (The system cannot find the path specified)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:292)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:185)
at com.ebook.dal.BookDAO.postBook(BookDAO.java:59)
at com.ebook.services.BookService.addNewBook(BookService.java:38)
at com.ebook.resources.BookResource.postNewBook(BookResource.java:72)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$TypeOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:219)
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:253)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:680)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:392)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:365)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:318)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:492)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:165)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:1025)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:452)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1201)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:654)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:317)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:835)
Oct 11, 2020 3:32:40 PM org.apache.catalina.core.StandardContext reload
答案1
得分: 0
你在这里混合使用了类路径和本地文件系统路径。在不清楚自己在做什么的情况下,不应该尝试这样覆盖类路径中的元素,因为这可能会在重新启动应用程序时引起行为异常。只需将其放在文件系统的某个位置,并始终在那里进行读写操作。
英文:
You are mixing classpath and local file system paths here. You should never try to overwrite elements in the classpath like that without knowing what you're doing as that would potentially charge the behavior of the app when you restart it. Just put the somewhere on the file system and consistently read and write there.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论