zoukankan      html  css  js  c++  java
  • Core Java笔记 6.部署应用程序

    本章重点:

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

    JAR 文件

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

    JAR 命令:

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

    manifest

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

    manifest 结构

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

    可运行 JAR 文件

    jar cvfe MyProgram.jar corejava.reflection.MethodPointerTest corejava
    

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

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

    java -jar MyProgram.jar 即可运行.

    Java Resource

    应用程序的资源可以是:

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

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

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

    package corejava.resource;
    
    import javax.swing.*;
    import java.awt.*;
    import java.io.InputStream;
    import java.net.URL;
    import java.util.Scanner;
    
    /**
     * Created by guolong.fan on 15/4/27.
     */
    public class ResourceTest {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    ResourceTestFrame frame = new ResourceTestFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setVisible(true);
                }
            });
        }
    
    }
    
    class ResourceTestFrame extends JFrame {
    
        public ResourceTestFrame() {
            setTitle("ResourceTest");
            setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    
            URL aboutURL = getClass().getResource("about.gif");
            Image img = Toolkit.getDefaultToolkit().getImage(aboutURL);
            setIconImage(img);
    
            JTextArea textArea = new JTextArea();
            InputStream stream = getClass().getResourceAsStream("about.txt");
            Scanner in = new Scanner(stream);
            while (in.hasNext()) {
                textArea.append(in.nextLine() + "
    ");
            }
            add(textArea);
        }
    
        public static final int DEFAULT_WIDTH = 300;
        public static final int DEFAULT_HEIGHT = 300;
    }
    

    应用程序的配置

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

    put & store & load & get

    Properties

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

    package corejava.resource;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    /**
     * Created by guolong.fan on 15/4/27.
     */
    public class PropertiesTest {
    
        public static void main(String[] args) {
    
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    PropertiesFrame frame = new PropertiesFrame();
                    frame.setVisible(true);
                }
            });
        }
    }
    
    class PropertiesFrame extends JFrame {
    
        public PropertiesFrame() {
    
            // Properties
            String userDir = System.getProperty("user.home");
            File propertiesDir = new File(userDir, ".corejava");
    
            if (!propertiesDir.exists()) propertiesDir.mkdir();
            properitesFile = new File(propertiesDir, "program.properties");
    
            // 设置默认设置
            Properties defaultSettings = new Properties();
            defaultSettings.put("left", "0");
            defaultSettings.put("top", "0");
            defaultSettings.put("width", "" + DEFAULT_WIDTH);
            defaultSettings.put("height", "" + DEFAULT_HEIGHT);
            defaultSettings.put("title", "");
    
            setting = new Properties(defaultSettings);
            if (properitesFile.exists()) try {
    
                // 如果文件存在,则从文件导入
                FileInputStream in = new FileInputStream(properitesFile);
                setting.load(in);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
    
            int left = Integer.parseInt(setting.getProperty("left"));
            int top = Integer.parseInt(setting.getProperty("top"));
            int width = Integer.parseInt(setting.getProperty("width"));
            int height = Integer.parseInt(setting.getProperty("height"));
            setBounds(left, top, width, height);
    
            String title = setting.getProperty("title");
            if (title.equals("")) title = JOptionPane.showInputDialog("Please supply a frame title");
            if (title == null) title = "";
            setTitle(title);
    
            // 关闭 window 时 将当前设置写入配置文件中
            addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent windowEvent) {
                    setting.put("left", "" + getX());
                    setting.put("top", "" + getY());
                    setting.put("width", "" + getWidth());
                    setting.put("height", "" + getHeight());
                    setting.put("title", getTitle());
    
                    try {
                        FileOutputStream out = new FileOutputStream(properitesFile);
                        setting.store(out, "Program Properties");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                    super.windowClosing(windowEvent);
                }
            });
    
    
        }
    
        private File properitesFile;
        private Properties setting;
    
        public static final int DEFAULT_WIDTH = 300;
        public static final int DEFAULT_HEIGHT = 300;
    }
    

    生成的配置文件:

    #Program Properties
    #Sun May 03 17:11:24 CST 2015
    height=336
    width=420
    left=360
    top=23
    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.

    String get(String key, String defVal);
    int getInt(String key, int defVal);
    ... ...
    put(String key, String value);
    putInt(String key, int value);
    ... ...
    

    采用 XML 格式导入/导出.

    void exportSubtree(OutputStream out);
    void exportNode(OutputStream out);
    
    void importPreferences(InputStream in);
    
  • 相关阅读:
    高盛、沃尔玛 题做出来还挂了的吐槽
    amazon师兄debrief
    到所有人家距离之和最短的中点 296. Best Meeting Point
    问问题没人回答的情况怎么办终于有解了
    找名人 277. Find the Celebrity
    数组生存游戏 289. Game of Life
    547. Number of Provinces 省份数量
    428. Serialize and Deserialize Nary Tree 序列化、反序列化n叉树
    alias别名简介和使用
    面试官:线程池执行过程中遇到异常会发生什么,怎样处理? Vincent
  • 原文地址:https://www.cnblogs.com/nil2inf/p/4474341.html
Copyright © 2011-2022 走看看