Java应用部署:JAR文件与应用偏好存储全解析
发布时间: 2025-08-18 00:07:27 阅读量: 2 订阅数: 11 

### Java应用部署:JAR文件与应用偏好存储全解析
#### 1. JAR文件基础
JAR(Java Archive)文件是Java中一种重要的文件格式,它可以将多个类文件、图像、资源文件等打包成一个单独的文件,方便程序的分发和部署。在操作JAR文件时,`jar` 命令提供了丰富的选项,下面是一些常用选项的介绍:
| 选项 | 描述 |
| --- | --- |
| c | 创建一个新的或空的存档,并将文件添加到其中。如果指定的文件名是目录,`jar` 程序会递归处理。 |
| C | 临时更改目录。例如,`jar cvf JARFileName.jar -C classes *.class` 会切换到 `classes` 子目录以添加类文件。 |
| e | 在清单中创建一个入口点。 |
| f | 指定JAR文件名作为第二个命令行参数。如果缺少此参数,`jar` 将在创建JAR文件时将结果写入标准输出,或在提取或列出JAR文件时从标准输入读取。 |
| i | 创建一个索引文件,用于加快在大型存档中的查找速度。 |
| m | 向JAR文件添加清单。清单是对存档内容和来源的描述。 |
| M | 不为条目创建清单文件。 |
| t | 显示目录列表。 |
| u | 更新现有的JAR文件。 |
| v | 生成详细输出。 |
| x | 提取文件。如果提供一个或多个文件名,则只提取这些文件;否则,提取所有文件。 |
| 0 | 不使用ZIP压缩存储。 |
#### 2. 清单文件
每个JAR文件除了包含类文件、图像和其他资源外,还包含一个清单文件 `MANIFEST.MF`,它位于JAR文件的 `META-INF` 子目录中。最小合法的清单文件很简单,只包含 `Manifest-Version: 1.0`。复杂的清单文件可以有更多的条目,这些条目被分组到各个部分。第一部分称为主部分,适用于整个JAR文件;后续条目可以指定命名实体(如单个文件、包或URL)的属性,这些条目必须以 `Name` 条目开头,各部分之间用空行分隔。
编辑清单文件时,将想要添加到清单的行放入一个文本文件,然后运行 `jar cfm JARFileName ManifestFileName ...` 命令。例如,创建一个带有清单的新JAR文件可以使用 `jar cfm MyArchive.jar manifest.mf com/mycompany/mypkg/*.class`;更新现有JAR文件的清单可以使用 `jar ufm MyArchive.jar manifest-additions.mf`。
#### 3. 可执行JAR文件
可以使用 `jar` 命令的 `e` 选项指定程序的入口点,即通常在调用 `java` 程序启动器时指定的类:
```bash
jar cvfe MyProgram.jar com.mycompany.mypkg.MainAppClass files to add
```
也可以在清单中指定程序的主类,包含如下形式的语句:
```plaintext
Main-Class: com.mycompany.mypkg.MainAppClass
```
注意,主类名不要添加 `.class` 扩展名,并且清单的最后一行必须以换行符结尾,否则清单将无法正确读取。
使用上述两种方法之一后,用户可以通过 `java -jar MyProgram.jar` 启动程序。根据操作系统配置,用户甚至可以通过双击JAR文件图标来启动应用程序:
- 在Windows上,Java运行时安装程序会为 `.jar` 扩展名创建文件关联,使用 `javaw -jar` 命令启动文件。
- 在Solaris上,操作系统会识别JAR文件的“魔数”,并使用 `java -jar` 命令启动。
- 在Mac OS X上,操作系统会识别 `.jar` 文件扩展名,双击JAR文件时执行Java程序。
不过,JAR文件中的Java程序与本地应用程序的感觉不同。在Windows上,可以使用第三方包装工具将JAR文件转换为Windows可执行文件,如Launch4J和IzPack;在Mac上,XCode中的Jar Bundler工具可以将JAR文件转换为一流的Mac应用程序。
#### 4. 资源文件
在Java中,类通常会有相关的数据文件,如图像、声音文件、包含消息字符串和按钮标签的文本文件,以及包含二进制数据的文件等,这些相关文件被称为资源。与Windows资源不同,Java资源作为单独的文件存储,而不是类文件的一部分,每个程序需要自行访问和解释资源数据。
要使用资源文件,可以按照以下步骤操作:
1. 获取具有资源的类的 `Class` 对象,例如 `AboutPanel.class`。
2. 如果资源是图像或音频文件,调用 `getResource(filename)` 方法获取资源位置的URL,然后使用 `getImage` 或 `getAudioClip` 方法读取。
3. 对于非图像或音频文件的资源,使用 `getResourceAsStream` 方法读取文件中的数据。
例如,创建一个带有图像文件 `about.gif` 的图标可以使用以下代码:
```java
URL url = ResourceTest.class.getResource("about.gif");
Image img = new ImageIcon(url).getImage();
```
读取文件 `about.txt` 可以使用以下代码:
```java
InputStream stream = ResourceTest.class.getResourceAsStream("about.txt");
Scanner in = new Scanner(stream, "UTF-8");
```
资源文件可以放在类文件的同一目录中,也可以放在子目录中,使用分层资源名,如 `data/text/about.txt`。资源名以 `/` 开头的称为绝对资源名。
下面是一个演示资源加载的示例程序:
```java
package resource;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
/**
* @version 1.41 2015-06-12
* @author Cay Horstmann
*/
public class ResourceTest {
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame frame = new ResourceTestFrame();
frame.setTitle("ResourceTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
/**
* A frame that loads image and text resources.
*/
class ResourceTestFrame extends JFrame {
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 300;
public ResourceTestFrame() {
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
URL aboutURL = getClass().getResource("about.gif");
Image img = new ImageIcon(aboutURL).getImage();
setIconImage(img);
JTextArea textArea = new JTextArea();
InputStream stream = getClass().getResourceAsStream("about.txt");
try (Scanner in = new Scanner(stream, "UTF-8")) {
while (in.hasNext()) {
textArea.append(in.nextLine() + "\n");
}
}
add(textArea);
}
}
```
#### 5. 包密封
可以密封Java语言包,以确保没有其他类可以添加到该包中。如果代码中使用了包可见的类、方法和字段,就需要密封包,否则其他类可以将自己放入同一个包中,从而访问其包可见的特性。
要密封一个包,将该包的所有类放入一个JAR文件。默认情况下,JAR文件中的包是未密封的。可以通过在清单的主部分添加 `Sealed: true` 来更改全局默认设置。对于每个单独的包,可以在JAR文件清单中添加另一部分来指定是否密封,例如:
```plaintext
Name: com/mycompany/util/
Sealed: true
Name: com/mycompany/misc/
Sealed: false
```
密封包的具体操作步骤如下:
1. 创建一个包含清单指令的文本文件。
2. 运行 `jar cvfm MyArchive.jar manifest.mf files to add` 命令。
#### 6. 应用偏好存储
用户通常希望应用程序能够保存他们的偏好和自定义设置,并在应用程序重新启动时恢复。Java应用程序传统上采用的简单方法是将配置信息存储在属性文件中,下面将详细介绍属性映射和相关操作。
##### 6.1 属性映射
属性映射是一种存储键/值对的数据结构,常用于存储配置信息。它具有以下三个特点:
- 键和值都是字符串。
- 可以轻松地将映射保存到文件并从文件加载。
- 有一个用于默认值的辅助表。
Java中实现属性映射的类是 `Properties`。以下是使用属性映射的示例代码:
```java
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
public class PropertyExample {
public static void main(String[] args) {
Properties settings = new Properties();
settings.setProperty("width", "200");
settings.setProperty("title", "Hello, World!");
try (OutputStream out = new FileOutputStream("program.properties")) {
settings.store(out, "Program Properties");
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
上述代码创建了一个属性映射,并将其保存到 `program.properties` 文件中。文件内容如下:
```plaintext
#Program Properties
#Mon Apr 30 07:22:52 2007
width=200
title=Hello, World!
```
要从文件加载属性,可以使用以下代码:
```java
import java.io.FileInpu
```
0
0
相关推荐









