[关闭]
@gnudennis 2015-05-03T19:18:54.000000Z 字数 6649 阅读 1359

Core Java笔记 6.部署应用程序

CoreJava


本章重点:

  • JAR 文件
  • Java Resource
  • 应用程序的配置

JAR 文件

JAR 可以将 Java 应用程序打包,JAR 文件可以包含类文件,也可以包含资源文件. JAR 文件采用 ZIP 压缩格式.

JAR 命令:

  1. Desktop jar cvf sample.jar corejava | iconv -f gbk -t utf-8
  2. 标明清单(manifest)
  3. 增加:corejava/(读入= 0) (写出= 0)(存储了 0%)
  4. 增加:corejava/.DS_Store(读入= 6148) (写出= 425)(压缩了 93%)
  5. 增加:corejava/inheritance/(读入= 0) (写出= 0)(存储了 0%)
  6. 增加:corejava/inheritance/ArrayStoreExceptionTest.class(读入= 787) (写出= 455)(压缩了 42%)
  7. 增加:corejava/inheritance/Base.class(读入= 651) (写出= 391)(压缩了 39%)
  8. 增加:corejava/inheritance/DynamicBinding.class(读入= 654) (写出= 386)(压缩了 40%)
  9. 增加:corejava/inheritance/Sub.class(读入= 546) (写出= 354)(压缩了 35%)
  10. 增加:corejava/inner/(读入= 0) (写出= 0)(存储了 0%)
  11. 增加:corejava/inner/InnerClassTest.class(读入= 744) (写出= 469)(压缩了 36%)
  12. 增加:corejava/inner/TalkingClock$TimePrinter.class(读入= 1315) (写出= 689)(压缩了 47%)
  13. 增加:corejava/inner/TalkingClock.class(读入= 933) (写出= 527)(压缩了 43%)
  14. 增加:corejava/interfaces/(读入= 0) (写出= 0)(存储了 0%)
  15. 增加:corejava/interfaces/CloneTest.class(读入= 1372) (写出= 757)(压缩了 44%)
  16. 增加:corejava/interfaces/Employee.class(读入= 1867) (写出= 994)(压缩了 46%)
  17. 增加:corejava/interfaces/Employee2.class(读入= 308) (写出= 227)(压缩了 26%)
  18. 增加:corejava/interfaces/ProxyTest.class(读入= 1427) (写出= 819)(压缩了 42%)
  19. 增加:corejava/interfaces/SortTest.class(读入= 599) (写出= 354)(压缩了 40%)
  20. 增加:corejava/interfaces/TimePrinter.class(读入= 1061) (写出= 580)(压缩了 45%)
  21. 增加:corejava/interfaces/TimerTest.class(读入= 854) (写出= 512)(压缩了 40%)
  22. 增加:corejava/interfaces/TraceHandler.class(读入= 1379) (写出= 762)(压缩了 44%)
  23. 增加:corejava/reflection/(读入= 0) (写出= 0)(存储了 0%)
  24. 增加:corejava/reflection/ArrayGrowTest.class(读入= 1897) (写出= 1054)(压缩了 44%)
  25. 增加:corejava/reflection/MethodPointerTest.class(读入= 1869) (写出= 992)(压缩了 46%)
  26. 增加:corejava/reflection/ObjectAnalyzer.class(读入= 3411) (写出= 1807)(压缩了 47%)
  27. 增加:corejava/reflection/ReflectionTest.class(读入= 4412) (写出= 2198)(压缩了 50%)

manifest

在生成 JAR 文件时,每个 JAR 文件还包含一个用于描述归档特征的清单文件(manifest),名为 MANIFEST.MF,位于 META-INF 子目录中(META-INF/MANIFEST.MF)。

manifest 结构

  1. Manifest-Version: 1.0
  2. 描述这个归档文件的行
  3. Name: Woozle.class
  4. 描述这个文件的行
  5. Name: com/mycompany/mypkg/
  6. 描述这个包的行

可运行 JAR 文件

  1. jar cvfe MyProgram.jar corejava.reflection.MethodPointerTest corejava

可以指定程序的入口. 在 manifest 会生成:

  1. Manifest-Version: 1.0
  2. Created-By: 1.6.0_65 (Apple Inc.)
  3. Main-Class: corejava.inheitance.ArrayStoreExceptionTest

java -jar MyProgram.jar 即可运行.

Java Resource

应用程序的资源可以是:

  • 图像和声音文件.
  • 带有消息字符串和按钮标签的文本文件.
  • 二进制数据文件.

Java 的资源不同 Windows, Windows 的资源属于 exe 文件的一部分,通过标准的程序设计访问;而 Java 资源作为单独的文件存储,不是类文件的一部分存储,对资源的访问和解释由每个类自己胜任.

对资源的访问和解释由每个类自己胜任.
e.g.

  1. package corejava.resource;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.io.InputStream;
  5. import java.net.URL;
  6. import java.util.Scanner;
  7. /**
  8. * Created by guolong.fan on 15/4/27.
  9. */
  10. public class ResourceTest {
  11. public static void main(String[] args) {
  12. EventQueue.invokeLater(new Runnable() {
  13. @Override
  14. public void run() {
  15. ResourceTestFrame frame = new ResourceTestFrame();
  16. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  17. frame.setVisible(true);
  18. }
  19. });
  20. }
  21. }
  22. class ResourceTestFrame extends JFrame {
  23. public ResourceTestFrame() {
  24. setTitle("ResourceTest");
  25. setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
  26. URL aboutURL = getClass().getResource("about.gif");
  27. Image img = Toolkit.getDefaultToolkit().getImage(aboutURL);
  28. setIconImage(img);
  29. JTextArea textArea = new JTextArea();
  30. InputStream stream = getClass().getResourceAsStream("about.txt");
  31. Scanner in = new Scanner(stream);
  32. while (in.hasNext()) {
  33. textArea.append(in.nextLine() + "\n");
  34. }
  35. add(textArea);
  36. }
  37. public static final int DEFAULT_WIDTH = 300;
  38. public static final int DEFAULT_HEIGHT = 300;
  39. }

应用程序的配置

对应用程序进行配置,并且将配置保存起来,当再次运行应用程序时读取配置。Java 提供了两种方式:Properties 和 Preference。

put & store & load & get

Properties

Property Map: 键/值对,通常用于存放配置信息.

  1. package corejava.resource;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.WindowAdapter;
  5. import java.awt.event.WindowEvent;
  6. import java.io.File;
  7. import java.io.FileInputStream;
  8. import java.io.FileOutputStream;
  9. import java.io.IOException;
  10. import java.util.Properties;
  11. /**
  12. * Created by guolong.fan on 15/4/27.
  13. */
  14. public class PropertiesTest {
  15. public static void main(String[] args) {
  16. EventQueue.invokeLater(new Runnable() {
  17. @Override
  18. public void run() {
  19. PropertiesFrame frame = new PropertiesFrame();
  20. frame.setVisible(true);
  21. }
  22. });
  23. }
  24. }
  25. class PropertiesFrame extends JFrame {
  26. public PropertiesFrame() {
  27. // Properties
  28. String userDir = System.getProperty("user.home");
  29. File propertiesDir = new File(userDir, ".corejava");
  30. if (!propertiesDir.exists()) propertiesDir.mkdir();
  31. properitesFile = new File(propertiesDir, "program.properties");
  32. // 设置默认设置
  33. Properties defaultSettings = new Properties();
  34. defaultSettings.put("left", "0");
  35. defaultSettings.put("top", "0");
  36. defaultSettings.put("width", "" + DEFAULT_WIDTH);
  37. defaultSettings.put("height", "" + DEFAULT_HEIGHT);
  38. defaultSettings.put("title", "");
  39. setting = new Properties(defaultSettings);
  40. if (properitesFile.exists()) try {
  41. // 如果文件存在,则从文件导入
  42. FileInputStream in = new FileInputStream(properitesFile);
  43. setting.load(in);
  44. } catch (IOException ex) {
  45. ex.printStackTrace();
  46. }
  47. int left = Integer.parseInt(setting.getProperty("left"));
  48. int top = Integer.parseInt(setting.getProperty("top"));
  49. int width = Integer.parseInt(setting.getProperty("width"));
  50. int height = Integer.parseInt(setting.getProperty("height"));
  51. setBounds(left, top, width, height);
  52. String title = setting.getProperty("title");
  53. if (title.equals("")) title = JOptionPane.showInputDialog("Please supply a frame title");
  54. if (title == null) title = "";
  55. setTitle(title);
  56. // 关闭 window 时 将当前设置写入配置文件中
  57. addWindowListener(new WindowAdapter() {
  58. @Override
  59. public void windowClosing(WindowEvent windowEvent) {
  60. setting.put("left", "" + getX());
  61. setting.put("top", "" + getY());
  62. setting.put("width", "" + getWidth());
  63. setting.put("height", "" + getHeight());
  64. setting.put("title", getTitle());
  65. try {
  66. FileOutputStream out = new FileOutputStream(properitesFile);
  67. setting.store(out, "Program Properties");
  68. } catch (IOException e) {
  69. e.printStackTrace();
  70. }
  71. super.windowClosing(windowEvent);
  72. }
  73. });
  74. }
  75. private File properitesFile;
  76. private Properties setting;
  77. public static final int DEFAULT_WIDTH = 300;
  78. public static final int DEFAULT_HEIGHT = 300;
  79. }

生成的配置文件:

  1. #Program Properties
  2. #Sun May 03 17:11:24 CST 2015
  3. height=336
  4. width=420
  5. left=360
  6. top=23
  7. title=PropertiesTest

put & store & load & get

  1. setting.load(in);
  2. setting.put(xx, xx);
  3. setting.store(out, "Program Properties");
  4. setting.getProperty("left");

Prefrences

Properties 类简化读取和保存配置. 但是配置文件存放无法放在主目录中(有些操作系统没有主目录的概念); 没有标准的配置文件命名的规则,导致配置文件名冲突.

Java SE 1.4 提供了 Preferences 类提供一个与平台无关的中心知识库.中心知识库实现是透明,通常 Windows 采用注册表,而 Linux 采用放在本地文件系统中.

Preferences 的中心知识库采用树状结构,每个节点的路径类似于包名,这样可以避免命名冲突。每个节点都有一个用来存放 key/value 的独立表。

为了增加灵活性,系统中有多棵并行的树。系统树用来存放全体用户的公共信息,每个程序的使用者拥有一棵树。Preferences 类操作的是'当前用户'的用户树。

访问用户树: Preferences root = Preferences.userRoot();
访问系统树: Preferences root = Preferences.systemRoot();
访问具体节点(通过路径名): Preferences node = root.node("/com/mycompany/myapp");
访问具体节点(通过包名): Preferences node = Preferences.userNodeForPackage(obj.getClass()); or Preferences node = Preferences.systemNodeForPackage(obj.getClass());

通过节点来 get/put.

  1. String get(String key, String defVal);
  2. int getInt(String key, int defVal);
  3. ... ...
  4. put(String key, String value);
  5. putInt(String key, int value);
  6. ... ...

采用 XML 格式导入/导出.

  1. void exportSubtree(OutputStream out);
  2. void exportNode(OutputStream out);
  3. void importPreferences(InputStream in);
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注