我已经使用 ResorceLoder 类来获取输入流,但是我如何获取 outputStream,这是否可以修改该包中的数据?(我需要使用存在于相同的jar文件)
3 回答
您不能在运行时直接更改 jar 文件的资源。ClassLoader(它为您提供那些 InputStreams 不提供 OutputStream 来重写 jar 文件中的文件)。
如果您想在运行时操作类似的图像或资源,请不要将它们放在您的 jar 文件中,而是从文件系统中检索它们。
更改类路径资源要么困难要么不可能……取决于类加载器和类路径。
如果类路径资源在文件系统目录中,您应该能够替换它。但是,文件可能被锁定,并且无法保证更新的资源在重新启动 JVM 之前可见。
如果类路径资源位于本地文件系统中的 JAR 或 ZIP 中,您还有几个额外的问题:
您不能对 JAR 或 ZIP 文件进行就地更新。您必须创建一个新的 ZIP / JAR 并将现有内容复制到其中。
类路径上的 ZIP 或 JAR 文件将被锁定。
如果类路径资源位于已下载的 ZIP 或 JAR 中,则(通常)无法在源代码处更新文件……因此您的更改可能不会“坚持”。
如果您使用的是自定义类加载器,那么所有的赌注都没有......
简而言之,最好找到一种不同的方法来做到这一点;例如,将资源复制/安装到文件系统中的可写目录中并从那里访问它们。
好的.. 如果我正确理解您的问题,您希望通过位于同一位置的程序文件更改类路径中的资源。我认为,如果您了解以下限制,这应该不是问题:
类加载器永远不会为您提供资源句柄(位于 jar 中)作为具有目录路径和所有文件的文件。这是因为 Jar 通常不会爆炸。为了将资源作为文件获取,您需要将 jar 分解为展开形式。
当您运行程序时,您当前的工作目录可能不是类路径中资源/jar 的位置。
您需要弄清楚资源的目录,然后您可以轻松地修改或做您想做的事情。
一种方法是在可配置文件中的某处声明您的资源路径。这是一个非常简单的方法。
另一种方法是使用逻辑找出路径。一个这样的例子来自这个链接
try { //Attempt to get the path of the actual JAR file, because the working directory is frequently not where the file is. //Example: file:/D:/all/Java/TitanWaterworks/TitanWaterworks-en.jar!/TitanWaterworks.class //Another example: /D:/all/Java/TitanWaterworks/TitanWaterworks.class PROGRAM_DIRECTORY = getClass().getClassLoader().getResource("TitanWaterworks.class").getPath(); // Gets the path of the class or jar. //Find the last ! and cut it off at that location. If this isn't being run from a jar, there is no !, so it'll cause an exception, which is fine. try { PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('!')); } catch (Exception e) { } //Find the last / and cut it off at that location. PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('/') + 1); //If it starts with /, cut it off. if (PROGRAM_DIRECTORY.startsWith("/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(1, PROGRAM_DIRECTORY.length()); //If it starts with file:/, cut that off, too. if (PROGRAM_DIRECTORY.startsWith("file:/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(6, PROGRAM_DIRECTORY.length()); } catch (Exception e) { PROGRAM_DIRECTORY = ""; //Current working directory instead. }