The Program
< Back to Main Page
// start SysClass.java
///////////////////////////////////////////////////////////////////////////////\
// Brueckner, Scott
// COP2805 E001 99001, Thu 7:00-9:45 pm, Seat 24
// Programming Project 1, Due Date 11-11-1999
//
// SysClass.java: Java application to demonstrate some features of Java's
// System class. It also demonstrates some rudimentary keyboard
// and disk file handling.
//
// Notes:
//
// This program scratches the surface of Java's System class. It's main
// function is to "ask" the system (via the System class) for a couple of its
// "properties," and use these properties to assist in writing a list of ALL
// system properties to a text file. You can then review the text file to see
// what properties the System class reports.
//
// This is not a particularly "robust" application, and will bomb-out to the
// operating system on any exception. A "real" application should provide
// exception handling.
//
// This program was compiled and run in the following environments:
//
// - Java 1.1 on a Linux (Unix) platform
// - Java 1.2 ("Java 2") on a Windows 95 platform
//
// Since the program needed to run under Java 1.1, I wasn't able to use
// methods that were introduced in Java 1.2. Of particular interest is the
// setProperty() method.
//
// In Java 1.2, you can easily change existing system properties (and add new
// properties) with the System.setProperty() method. Based on the API
// documentation, it looks like there might be a way to do this under Java
// 1.1, but I didn't have time to experiment. It's worth noting that the
// setProperty() method does _not_ permanently change system properties; the
// changes are only in effect during the execution of the program.
//
// This program will ask you for a file name. The list of system properties
// will then be written to this file in the current directory. The program
// will _not_ overwrite an existing file, but it _will_ bomb-out if you
// specify an illegal file name.
//
// I recommend that you keep the file name short (even just one or two
// characters) or the screen output will "wrap."
///////////////////////////////////////////////////////////////////////////////\
import java.io.*;
import java.util.*;
/////////////////////
public class SysClass
/////////////////////
{
///////////////////////////////////////////////////////
public static void main(String args[]) throws Exception // Bombs on exception
///////////////////////////////////////////////////////
{
// The first few lines of code get the "line separator" from the system.
// This is the character (or characters) used to terminate lines in
// text files. Also, the line separator is added to the keyboard input
// stream (System.in) when the user presses the ENTER key.
//
// The line separator is platform-specific. The standard line separators
// for the major microcomputer platforms are:
//
// DOS: CarriageReturn/LineFeed ("\r\n")
// Unix: LineFeed ("\n")
// Mac: CarriageReturn ("\r")
String stLineSep; // String containing the system line separator
int iLineSepLength; // Length of the line separator
int iLineSepEnd; // Last character of the line separator
// Line separator:
stLineSep = System.getProperty("line.separator"); // Get it
iLineSepLength = stLineSep.length(); // Length
iLineSepEnd = stLineSep.charAt(iLineSepLength - 1); // Last character
// The next statement creates a File object corresponding to the current
// directory (where we'll create the output file).
//
// The "file separator" is the system property containing the character (or
// characters) that delimits file and directory names. Again, this is
// platform-specific:
//
// DOS: \ (backslash)
// Unix: / (forward slash)
// Mac: I don't know
//
// In the DOS and Unix environments, the current directory can be referenced
// as a period (.) followed by the file separator:
//
// DOS: .\
// Unix: ./
//
// Using the "file.separator" property from the system makes the application
// portable to different platforms. (At least between DOS and Unix. I don't
// know for sure if this works on a Mac, although I expect it does).
File filDir = new File("." + System.getProperty("file.separator"));
int iThisChar; // To read individual chars with System.in.read()
boolean bError; // Entry error flag
StringBuffer bufOutputFileName = new StringBuffer(); // Buffer for file name
File filOutput = new File(""); // Output disk file
System.out.println(
"\nThis program writes a list of the current system properties");
System.out.println("to a text file in the current directory.");
do // while (bError)
{
bError = false; // Clear error flag
bufOutputFileName.setLength(0); // Truncate file name buffer
System.out.print("\nPlease enter a name for the text file: "); // Prompt
// The next block reads the keyboard input one character at a time until
// it encounters the last character of the system line separator. This
// will presumably be the end of the keyboard buffer. It retains ALL
// characters read, including the line separator, so we can see what
// really came in from the keyboard.
//
// This logic won't work if the last character of the line separator
// occurs more than once in the line separator, but as far as I know,
// this doesn't happen (at least it doesn't on PCs, Unix boxes, or Macs).
//
// You probably wouldn't do it this way in practice. Using a
// 'BufferedReader' is much easier, and it takes care of the details for
// you, including removing the line separator.
do
{
iThisChar = System.in.read(); // Get the next char
bufOutputFileName.append( (char) iThisChar ); // Add it to the buffer
System.out.print(" " + iThisChar); // Display ASCII value
} while (iThisChar != iLineSepEnd);
System.out.println(" <-- ASCII codes input");
// Display length before removing the line separator
System.out.println(" " +
"Length of input BEFORE removing line separator = " +
bufOutputFileName.length());
// Remove the line separator
bufOutputFileName.setLength(bufOutputFileName.length() - iLineSepLength);
// Display length after removing the line separator
System.out.println(" " +
"Length of input AFTER removing line separator = " +
bufOutputFileName.length());
// Display ASCII values of remaining characters
for (int i = 0; i < bufOutputFileName.length(); i++)
System.out.print(" " + (int) bufOutputFileName.charAt(i));
System.out.println(" <-- ASCII codes retained");
if (bufOutputFileName.length() == 0) // User didn't enter anything
{
System.out.println("\n Please enter SOMETHING.");
bError = true;
continue;
}
// Create an new File object in the current directory. This doesn't
// actually create the file, only a reference to it. If the user enters
// an illegal file name (based on the underlying operating system), an
// exception will be thrown when an attempt is made to create the file.
filOutput = new File(filDir, bufOutputFileName.toString());
// The next clause disallows the file name if the file already exists or
// if there is a directory of the same name in the current directory. A
// "real" application should probably allow the user to overwrite an
// existing file. On the platforms tested, the exists() method was able
// to see "hidden" files.
//
// In Java 1.2, you can use File.createNewFile() and check its return
// value to see if the file was really created (createNewFile() returns
// 'false' if the file already exists, and unlike C, it won't truncate
// an existing file). The createNewFile() method wasn't introduced until
// until Java 1.2; I couldn't use it since my test Linux platform is
// running Java 1.1.
if (filOutput.exists())
{
if (filOutput.isDirectory())
System.out.println("\n " + filOutput + " is a directory.");
else
System.out.println("\n File already exists.");
bError = true;
continue;
}
} while (bError);
// Attach a buffered output stream to the File object. This statement
// creates the disk file with a length of zero bytes (since it doesn't
// already exist). If we had used File.createNewFile() (in Java 1.2) above,
// the file would already be created.
//
// If the user entered an illegal file name, a FileNotFoundException will
// be thrown. A "real" application should handle this.
BufferedWriter bufOutputStream = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(filOutput)));
// Get the system property list. If a Security Manager is operating, it may
// not allow this (it will throw a SecurityException). Even if this is true,
// it _may_ allow explicit access to individual properties with the
// System.getProperty(String) method.
Properties prSystemProperties = System.getProperties();
String stPropertyKey; // Current system property key (name)
String stPropertyValue; // Current system property value
// We'll pull out the individual properties with an enumerator. Iterators
// are nicer, but the Properties.propertyNames() method returns an
// Enumeration object.
//
// It would be nice to sort the list, but I wasn't that ambitious. Also,
// notice that the 'for' header doesn't contain an increment.
for (
Enumeration e = prSystemProperties.propertyNames();
e.hasMoreElements();
)
{
stPropertyKey = ( (String) e.nextElement() ); // Property name
stPropertyValue = System.getProperty(stPropertyKey); // Get property value
// Write the name of the property to the file. This will write in ASCII
// (one byte characters). If you want Unicode output (two byte characters,
// use writeChars() instead of write().
bufOutputStream.write(stPropertyKey + " = ");
// Write the value of the property to the file. We'll handle the line
// separator differently. Since 'line.separator' contains the characters
// that actually make up the line separator, if we write it "as is," it
// will just produce a blank line. Instead, we'll write the ASCII value(s)
// as int(s).
if (stPropertyKey.equals("line.separator"))
for (int i = 0; i < iLineSepLength; i++)
bufOutputStream.write( (int) stPropertyValue.charAt(i) + " " );
else
bufOutputStream.write(stPropertyValue);
// The next statement writes the line separator to the file, causing an
// advance to the next line. This will create a text file in the proper
// format for the current platform.
//
// If you wanted to create a text file for a specific (possibly different)
// operating system, you could use one of the following statements
// instead:
//
// bufOutputStream.write("\r\n"); // DOS (carriage return / line feed)
// bufOutputStream.write("\n"); // Unix (line feed)
// bufOutputStream.write("\r"); // Mac (carriage return)
//
// Note that if you follow the common practice of just blindly using a
// "\n" to terminate the lines, you're actually creating a UNIX text file.
// Other operating systems may not display the file correctly.
bufOutputStream.write(stLineSep);
} // end for (Enumeration e)
// Be sure to close the file. This is particularly important for buffered
// output streams. My testing indicated that all bytes might not be written
// unless the file is explicitly closed.
bufOutputStream.close();
System.out.println("\nSystem properties written to " + bufOutputFileName);
return;
} // end main()
} // end class SysClass
// end SysClass.java
< Back to Main Page | ^ Up to Top