While Java is designed to be
portable, there are some things
that 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
backwards 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 |
|
DOS |
dir/s |
Directory with subdirectories option (i.e., recursive) of , the top-level directory (but only of the current drive) |
|
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; the Mac, for example, uses :
between
filenames and directories. Java has two solutions to this. First,
when moving between Unix and Microsoft systems, at least, it is
permissive: either / or can be used, 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 10) 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:
Name |
Type |
Meaning |
---|---|---|
|
|
The system-dependent filename separator character, e.g., / or |
|
|
The system-dependent filename separator character, e.g., / or |
|
|
The system-dependent path separator character, represented as a string for convenience |
|
|
The system-dependent path separator character |
Both filename and path separators are normally characters, but are
also available in String
form for convenience.
A second, more general, mechanism is the system Properties object mentioned in Section 2.3. 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 "jnk" otherwise. */ public static String getDevNull( ) { String sys = System.getProperty("os.name"); if (sys==null || sys.indexOf("Mac") >= 0) return "junk"; if (sys.startsWith("Windows")) return "NUL:"; return "/dev/null"; } }
18.118.137.7