Recipe 2.4 Writing Operating System-Dependent Code


Problem

You need to write code that depends on the underlying operating system.

Solution

Again, don't do this. Or, if you must, use System.properties.

Discussion

While Java is designed to be portable, some things aren't. These include such variables as the filename separator. Everybody on Unix knows that the filename separator is a slash character ( / ) and that a backward slash, or backslash ( \ ), is an escape character. Back in the late 1970s, a group at Microsoft was actually working on Unix their version was called Xenix, later taken over by SCO and the people working on DOS saw and liked the Unix filesystem model. MS-DOS 2.0 didn't have directories, it just had "user numbers" like the system it was a clone of, Digital Research CP/M (itself a clone of various other systems). So the Microsoft folk set out to clone the Unix filesystem organization. Unfortunately, they had already committed the slash character for use as an option delimiter, for which Unix had used a dash (- ); and the PATH separator (:) was also used as a "drive letter" delimiter, as in C: or A:. So we now have commands like this:

System

Directory list command

Meaning

Example PATH setting

Unix

ls -R /

Recursive listing of /, the top-level directory

PATH=/bin:/usr/bin

DOS

dir/s \

Directory with subdirectories option (i.e., recursive) of \, the top-level directory (but only of the current drive)

PATH=C:\windows;D:\mybin


Where does this get us? If we are going to generate filenames in Java, we need to know whether to put a / or a \ or some other character. Java has two solutions to this. First, when moving between Unix and Microsoft systems, at least, it is permissive: either / or \ can be used,[2] and the code that deals with the operating system sorts it out. Second, and more generally, Java makes the platform-specific information available in a platform-independent way. First, for the file separator (and also the PATH separator), the java.io.File class (see Chapter 11) makes available some static variables containing this information. Since the File class is platform-dependent, it makes sense to anchor this information here. The variables are:

[2] When compiling strings for use on Windows, remember to double them, since \ is an escape character in most places other than the MS-DOS command line: String rootDir = "C:\\";.

Name

Type

Meaning

separator

static String

The system-dependent filename separator character e.g., / or \.

separatorChar

static char

The system-dependent filename separator character e.g., / or \.

pathSeparator

static String

The system-dependent path separator character, represented as a string for convenience.

pathSeparatorChar

static char

The system-dependent path separator character.


Both filename and path separators are normally characters, but they are also available in String form for convenience.

A second, more general, mechanism is the system Properties object mentioned in Recipe 2.2. You can use this to determine the operating system you are running on. Here is code that simply lists the system properties; it can be informative to run this on several different implementations:

import java.util.*; /**  * Demonstrate System Properties  */ public class SysPropDemo {     public static void main(String argv[]) {         System.out.println("System Properties:");         Properties p = System.getProperties( );         p.list(System.out);     } }

Some OSes, for example, provide a mechanism called "the null device" that can be used to discard output (typically used for timing purposes). Here is code that asks the system properties for the "os.name" and uses it to make up a name that can be used for discarding data. If no null device is known for the given platform, we return the name junk, which means that on such platforms, we'll occasionally create, well, junk files. I just remove these files when I stumble across them.

/** Some things that are System dependent.  * All methods are static, like java.lang.Math.  */ public class SysDep {     /** Return the name of the Null device on platforms which support it,      * or the string "junk" otherwise.      */     public static String getDevNull( ) {         String sys = System.getProperty("os.name");         if (sys==null)             return "junk";         if (sys.startsWith("Windows"))             return "NUL:";         return "/dev/null";     } }

In one case you do need to check for the OS. Mac OS X has a number of GUI goodies that can be used only on that OS and yet should be used to make your GUI application look more like a "native" Mac application. Recipe Recipe 14.16 explores this issue in more detail. In brief, Apple says to look for the string mrj.version to determine whether you are running on OS X:

boolean isMacOS = System.getProperty("mrj.version") != null;



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net