首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

14.2  系统工具

System类实现很多系统工具。在14.1节中已经介绍了一些。这一小节介绍一些其他的系统工具。

14.2.1  命令行I/O对象

System提供若干预定义的I/O对象,它们适用于需要从命令行启动的Java应用程序。这些对象实现大多数操作系统提供的标准I/O流,以及适用于输入密码的控制台对象。关于更多信息,参见10.1.5节。

14.2.2  系统属性

在14.1.1节中,我们分析了应用程序使用Properties对象维护其配置的方式。Java平台本身使用一个Properties对象维护它自己的配置。System类维护一个描述当前工作环境的配置的Properties对象。系统属性包括的信息和当前用户、Java运行时的当前版本以及用于分隔文件路径名部分的字符有关。

表14-1描述一些最重要的系统属性。

表14-1  一些重要的系统属性

含    义

"file.separator"

分隔文件路径部分的字符。在UNIX中是“/”;在Windows中是“\”

"java.class.path"

用于查找包含类文件的目录和JAR文件的路径。类路径的元素由path.separator属性中指定的平台特定的字符分隔

"java.home"

Java运行时环境(Java Runtime Environment,JRE)的安装目录

"java.vendor"

JRE厂商名称

"java.vendor.url"

JRE厂商的URL

"java.version"

JRE版本号

"line.separator"

操作系统用于分隔文本文件中的行的序列

"os.arch"

操作系统架构

"os.name"

操作系统名称

"os.version"

操作系统版本

"path.separator"

java.class.path中使用的路径分隔符

"user.dir"

用户工作目录

"user.home"

用户主目录

"user.name"

用户账户名

安全考虑 安全管理器限制对系统属性的访问。这在applet中经常是一个问题,它经常禁止读取某些系统属性,并且禁止写入任何系统属性。关于在applet中访问系统属性的更多信息,请参阅14.2.2节的第1小节。

1. 读取系统属性

System类有两个用于读取系统属性的方法:getProperty和getProperties。

System类的getProperty方法有两个不同版本。两个版本都获得实参列表中指定的属性的值。两个getProperty方法中比较简单的那个采用一个属性键作为实参。例如,为了获得path.separator的值,可以使用如下语句:

System.getProperty("path.separator");

getProperty方法返回包含这个属性的值的字符串。如果属性不存在,getProperty的这个版本返回null。

getProperty的另一个版本需要两个String实参:第一个实参是要搜索的键,如果找不到键或者键没有值,那么第二个实参就是返回的默认值。例如,下面的getProperty调用搜索名为subliminal.message的System属性。这不是合法的系统属性,所以这个方法没有返回null,而是返回第二个实参提供的默认值:“Buy StayPuft Marshmallows!”:

 

System.getProperty("subliminal.message",

                   "Buy StayPuft Marshmallows!");

System类提供的访问属性值的最后一个方法是getProperties,它返回一个Properties对象。这个对象包含系统属性定义的完整集合。

2. 写系统属性

为了修改现有的系统属性集合,需要使用System.setProperties。这个方法采用Properties对象作为实参,这个对象被初始化为包含要设置的属性。这个方法使用Properties对象代表的新集合替换整个系统属性集合。

警告 改变系统属性有潜在的危险性,并且应该慎重进行。很多系统属性在启动后不重新读取,并且用于提供信息。改变一些属性可能造成不可预计的副作用。

下一个示例PropertiesTest创建一个Properties对象,并且从myProperties.txt初始化它:

subliminal.message=Buy StayPuft Marshmallows!

然后PropertiesTest使用System.setProperties安装新的Properties对象作为当前系统属性的集合:

import java.io.FileInputStream;

import java.util.Properties;

public class PropertiesTest {

  public static void main(String[] args) throws Exception {

    // set up new properties object

    // from file "myProperties.txt"

    FileInputStream propFile = new FileInputStream(

                                      "myProperties.txt");

    Properties p = new Properties(System.getProperties());

    p.load(propFile);

    // set the system properties

    System.setProperties(p);

    // display new properties

    System.getProperties().list(System.out);

  }

}

注意PropertiesTest是如何创建Properties对象p的,它被用作setProperties的实参:

Properties p = new Properties(System.getProperties());

这个语句使用当前系统属性的集合,初始化新的属性对象p,这个集合在这个小应用程序示例中是运行时系统初始化的属性集合。然后,应用程序把附加的属性从文件myProperties.txt加载到p中,并且设置系统属性为p。结果是把myProperties.txt中列出的属性添加到了启动运行时系统创建的属性集合。注意,应用程序可以不使用任何默认的Properties对象创建p,比如:

Properties p = new Properties();

另外注意,系统属性的值可以被覆盖!例如,如果myProperties.txt包含如下一行,那么系统属性java.vendor就被覆盖了:

java.vendor=Acme Software Company

总的来说,注意不要覆盖系统属性。

setProperties方法改变当前运行中的应用程序的系统属性集合。这些改变不具有持久性。也就是说,即使在一个应用程序中改变系统属性,也不会影响Java解释器将来对这个应用程序或者其他应用程序的调用。运行时系统每次启动时重新初始化系统属性。如果对系统属性的改动需要持久化,那么应用程序就必须在退出之前把值写入某个文件,并且在启动时再次读取它们。

14.2.3  安全管理器

安全管理器(security manager)是定义应用程序安全策略的对象。这一策略指定不安全或者敏感的操作。安全策略不允许的任何操作都会抛出SecurityException异常。应用程序也可以查询其安全管理器,从而了解允许哪些操作。

典型情况下,Web applet在运行时使用浏览器或者Java Plug-in提供的安全管理器。其他类型的应用程序一般运行不带有安全管理器,除非应用程序本身定义了安全管理器。如果不带安全管理器,那么应用程序就没有安全策略,并且其操作不受限制。

这一节讲解应用程序如何和现有的安全管理器进行交互。更详细的信息,包括如何设计安全管理器的信息,请参阅安全指南(Security Guide)。

1. 和安全管理器进行交互

安全管理器是SecurityManager类型的对象,为了获得对这个对象的引用,需要调用System.getSecurityManager:

SecurityManager appsm = System.getSecurityManager();

如果没有安全管理器,这个方法则返回null。

应用程序具有了对安全管理器对象的引用之后,就可以请求进行特定操作的许可。标准库中的很多类都是这样。例如,System.exit使用退出状态终止Java虚拟机,它调用SecurityManager.checkExit确保当前线程具有关闭应用程序的许可。

SecurityManager定义了很多其他的用于验证其他类型操作的方法。例如,Security- Manager.checkAccess验证线程访问,SecurityManager.checkProperty Access验证对指定的属性的访问。每个操作或者操作组都有其自己的checkXXX()方法。

另外,checkXXX()方法的集合表示已经属于安全管理器保护范围的操作集合。典型情况下,应用程序不必直接调用任何checkXXX()方法。

2. 识别安全违规

很多平常不带有安全管理器的操作,当带有安全管理器运行时,可以抛出Security- Exception异常。即使调用没有指定为抛出SecurityException异常的方法,也是如此。例如,分析下面用于读取文件的代码:

reader = new FileReader("xanadu.txt");

没有安全管理器的情况下,这个语句的执行不出现错误,前提是xanadu.txt文件存在并且可读。但是,假设这个语句被插入到一个Web applet中,典型情况下Web applet在不允许文件输入的安全管理器之下运行。可能会出现下面的错误消息:

appletviewer fileApplet.html

Exception in thread "AWT-EventQueue-1"

  java.security.AccessControlException: access denied

  (java.io.FilePermission characteroutput.txt write)

  ...

注意这种情况下抛出的特定异常,java.security.AccessControlException是SecurityException的子类。

14.2.4  系统中的杂项方法

这一小节介绍前面几节没有提到的System中的一些方法。

arraycopy方法高效地在数组之间复制数据。关于更多信息,请参阅3.1.3节。

currentTimeMillis和nanoTime方法非常适于测量应用程序执行过程中的时间间隔。为了测量以毫秒为单位的时间间隔,可以在间隔的开始和结束时两次调用currentTimeMillis,然后从返回的第二个值中减去第一个值。类似的,可以两次调用nanoTime测量以纳秒为单位的时间间隔。

注意 currentTimeMillis和nanoTime的精度受到操作系统提供的时间服务的限制。不要假设currentTimeMillis精确到最接近的毫秒,或者nanoTime精确到最接近的纳秒。另外,不应该使用currentTimeMillis和nanoTime确定当前时间。可以使用高级方法,比如java.util.Calendar.getInstance。

exit方法使Java虚拟机关闭,带有实参指定的整数退出状态。退出状态可以被启动应用程序的进程使用。按照约定,退出状态0表示应用程序正常终止,而任何其他值都是错误码。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论