在Java中管理环境变量插图

介绍

变量被命名为内存位置。它们的值保存在内存中,我们通常记不起来,因为它们对人类不友好,而且会四处移动。不过,如果我们命名内存位置,比如a,就更容易记住。

环境变量与通常的编程变量非常相似,只是它们被设置在程序之外的某个地方。它可以被操作系统、JVM、我们的程序正在使用的微服务等使用。

更准确地说,它们是键/值对,其中键是可以被认为是环境变量的名称,值是,嗯,值。它们的值总是字符串。

当人们提到环境变量时,通常是指那些由操作系统设置的变量。在过去,您可能不得不处理PATHJAVA_HOME—这些都是环境变量。

环境变量因操作系统而异,有时很难制作依赖于环境变量的可移植程序,但没有什么会使它们天生难以使用。

操作系统的环境变量在JVM世界中有类似的属性。它们超出了本文的范围,但值得一提的是,它们在较小的范围内是一个非常相似的概念。

查询环境变量

操作系统将其环境变量存储为键/值对。你可以用System.getenv()检索这些值。如果不带参数使用它,则会得到一个Map对象作为返回值:

Map<String, String> env = System.getenv();

for(String envName : env.keySet()){
    System.out.println(String.format("%s : %s", envName, env.get(envName)));
}

以下是结果的截断视图:

PROCESSOR_ARCHITECTURE : AMD64
MIC_LD_LIBRARY_PATH : C:\Program Files (x86)\Common Files\Intel\Shared Libraries\compiler\lib\mic
PSModulePath : C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\
SystemDrive : C:
AWE_DIR : D:\Awesomium\1.6.6\
FPS_BROWSER_USER_PROFILE_STRING : Default
PATHEXT : .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
DriverData : C:\Windows\System32\Drivers\DriverData
HerokuPath : E:\Heroku
ProgramData : C:\ProgramData
ProgramW6432 : C:\Program Files

您还可以向它传递一个与变量名称(键)对应的字符串,它将以字符串形式返回相应变量的值:

System.out.println(System.getenv("NUMBER_OF_PROCESSORS"));
8

ProcessBuilder和环境

Java有一个处理操作系统进程的进程类。为了简化流程的创建,这里有一个ProcessBuilder类,您可以简单地将命令“添加”到它的实例中运行。

每个进程都可以有自己的环境。程序的环境将由操作系统设置,但作为进程启动的程序可以有一个修改过的“手工”环境。

要编辑环境,必须使用environment()的getter从ProcessBuilder对象获取其引用。就像从系统中读取环境变量一样,您将得到一个映射,然后可以使用通常的映射操作对其进行修改。

创建环境后,我们将创建一个命令。这取决于操作系统。在这里,我们有一个基本的检查,它充分地改变了命令:

// Setting up the environment...
ProcessBuilder processBuilder = new ProcessBuilder();
Map<String, String> env = processBuilder.environment();
env.put("PING_WEBSITE", "stackabuse.com");

if (System.getProperty("os.name").startsWith("Windows")) {
    processBuilder.command("cmd.exe", "/c", "ping -n 3 %PING_WEBSITE%")
} else {
    processBuilder.command("/bin/bash", "-c", "ping $PING_WEBSITE$");
}

try {
    // Starting the process...
    Process process = processBuilder.start();

    // Reading the output of the process
    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()))) {

        String line;

        while ((line = reader.readLine()) != null) {
             System.out.println(line);
        }
    }

    // Catch the exit code of our process
    int ret = process.waitFor();

    System.out.printf("Program exited with code: %d", ret);

} catch (IOException | InterruptedException e) {
    // Handle exception...
    e.printStackTrace();
}
Pinging stackabuse.com [172.67.218.223] with 32 bytes of data:
Reply from 172.67.218.223: bytes=32 time=12ms TTL=57
Reply from 172.67.218.223: bytes=32 time=12ms TTL=57
Reply from 172.67.218.223: bytes=32 time=15ms TTL=57

Ping statistics for 172.67.218.223:
    Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 12ms, Maximum = 15ms, Average = 13ms
Program exited with code: 0
Process finished with exit code 0

我们创建了一个新的环境变量,名为PING_WEBSITE,具有固定值。您可以修改此程序,将PING_WEBSITE的值设置为用户输入、命令行参数或从文件中读取值。

结论

我们已经介绍了环境变量的概念,解释了它们的用途和类似的概念,以及它们依赖于系统的性质。

然后,我们使用Java的System.getEnv()方法,以及使用ProcessBuilder创建进程和执行依赖于环境变量的命令。