Please support my sponors and make this site possible!!!
Please support our sponsors!

 

Home > Core Java FAQ > Input - Output FAQ
Input-OutPut
Input Output (38)
 
Q .  How do I do keyboard (interactive) I/O in Java?

Ans : 

Interactive I/O in Java is very poorly supported. Programmers must piece together several library classes in non-obvious ways to get the required functionality.

Q . Is there a way to read a char from the keyboard without having to type carriage-return?

Ans : 

You can do this in a GUI (e.g. in a text component). There is no pure Java way to do character-by-character I/O without using a GUI.

Q . How do I read a line of input at a time?

Ans : 

In the JDK 1.0.2, use the readLine method in the DataInputStream class; in the JDK 1.1, use readLine in either BufferedReader or LineNumberReader.

     The DataInputStream class is a hidden workhorse in the Java input/output system. The class exists chiefly to read various data types in binary format from an input stream. It also provides a readLine method for reading one line of input at a time.
     The readLine method reads from the current input position up to a line terminator. For cross-platform compatibility, readLine recognizes as line terminators the bytes for newline (\n), carriage return (\r), and the byte sequence newline-return (\n\r). Reaching the end of a file also counts as terminating an input line. Invoking readLine at the end of the input stream returns null.
     The following sample code defines a method that calculates the average line length of text in the input stream:

     /* using JDK 1.0.2: */
     public static float getAverageLineLength(InputStream in)
                         throws IOException {
         DataInputStream dataIn = new DataInputStream(in);
         String currentLine;
         int lineCount = 0;
         int charCount = 0;
         while ((currentLine = dataIn.readLine()) != null) {
             ++lineCount;
             charCount += currentLine.length();
         }
         return (charCount / (float) lineCount);
     }
     DataInputStream's readLine method reads bytes, but it outputs a Java string containing 2-byte Unicode characters. Each input byte gets translated to a Unicode character by using the input byte as the output character's low byte and setting the output character's high byte to zero. Thus, DataInputStream's readLine method assumes that each input byte is a 8-bit character, which renders the method unfit for reading lines of Unicode text in general.
     The JDK 1.1 fills in the Unicode input deficiency with a suite of ...Reader classes, which truly read Unicode input characters (Java's char type) rather than just byte streams. For line-oriented input, in particular, you can use the readLine method in either the BufferedReader or LineNumberReader classes. The sample method, rewritten to use LineNumberReader, follows:
     /* using JDK 1.1: */
     public static float getAverageLineLength(InputStream in)
                         throws IOException {
         LineNumberReader lineReader = new LineNumberReader(
                                           new InputStreamReader(in));
         String currentLine;
         int charCount = 0;
         while ((currentLine = lineReader.readLine()) != null) {
             charCount += currentLine.length();
         }
         return (charCount / (float) lineReader.getLineNumber());
     }
This example also illustrates using the InputStreamReader class to convert from a byte-oriented input stream to a char-oriented Reader. The LineNumberReader instance is then constructed from that Reader object.
Q . How do I read input from the user (or send output) analogous to using standard input and standard output in C or C++?

Ans : 

Use the standard system streams: System.in, System.out, and System.err.

     C and C++ define standard input/output libraries (collections of compiled functions) that rely heavily on three input/output streams, called standard input, standard output, and standard error. The analogue in Java to a library in C or C++ is a Java language package. Completing the analogy, the java.io package defines essentially the same three streams, which you access as fields of the System class:

  • System.in: standard input; the customary input stream for keyboard input when a program lacks a graphical user interface (GUI).
  • System.out: standard output; the customary output stream for programs that lack a GUI.
  • System.err: standard error; the customary output stream for error output in programs that lack a GUI.
System.in is an instance of InputStream and System.out and System.err are instances of class PrintStream.
     If you want just string output (to either System.out or System.err), the PrintStream methods print and println, together with the string concatenation operator +, provide straightforward tools that get the job done (in the JDK 1.0.2). For example, the following code prints the value of one int variable and one float variable to System.out:
     /* using JDK 1.0.2: */
     int intValue = 3;
     float floatValue = 3.1416F;
     System.out.println("My int value = " + intValue + ".");
     System.out.println("My float value = " + floatValue + ".");
     For proper handling of Unicode text, the JDK 1.1 supersedes many of the byte-stream input/output classes with Unicode text-oriented classes: Reader, Writer, and their many subclasses. The PrintStream class, for example, is superseded by the PrintWriter class, with its own version of print and println. Thus, to use println to write to the standard output, you build a PrintWriter instance from the underlying System.out byte stream:
     /* using JDK 1.1: */
     int intValue = 3;
     float floatValue = 3.1416F;
     PrintWriter writer;
     // Create a PrintWriter with autoflush set to true,
     // so that each newline will automatically flush the output.
     writer = new PrintWriter(System.out, true);
     writer.println("My int value = " + intValue + ".");
     writer.println("My float value = " + floatValue + ".");
     Warning: When migrating code from 1.0.2 to 1.1, you may encounter some nasty surprises unless you carefully match the automatic flushing behavior of System.out. Use PrintWriter's two-parameter constructor, with the second argument set to true; this ensures that the output will be flushed once for each newline you send.
     Reading from System.in is more complicated, depending on what format you're expecting to read the data in. System.in gives you a plain input byte stream, which has no idea of input formats and can read only one byte at a time. For more control over your input, you need to build a fuller-featured input stream around System.in, such as a DataInputStream instance. The following code fragment shows a DataInputStream instance reading one line of input at a time:
     /* using JDK 1.0.2: */
     String currentLine;
     DataInputStream inStream = new DataInputStream(System.in);
     try {
         while ((currentLine = inStream.readLine()) != null) {
             // ... process current line
         }
     } catch (IOException e) { /* ... */ }
         // ... handle exception
     }
Updating this code for JDK 1.1 primarily involves wrapping a BufferedReader instance around System.in :
     /* using JDK 1.1: */
     String currentLine;
     BufferedReader reader;
     reader = new BufferedReader(new InputStreamReader(System.in));
     try {
         while ((currentLine = reader.readLine()) != null) {
             // ... process current line
         }
     } catch (IOException e) { /* ... */ }
Q . Is there a standard way to read in int, long, float, and double values from a string representation?

Ans :

There is no one standard way, but there is a small group of methods and constructors that will do the job for you.

The java.lang package in the JDK 1.0.2 provides four classes for treating numbers as objects: Integer, Long, Float, and Double. Each of these classes provides constructors and methods that translate from a string to an instance of the class. You then need to invoke an additional <type>Value method to retrieve the numeric value of type <type> held in the numeric object. Alternatively, the Integer and Long classes provide additional parse<type> methods that make the conversion in one step. These techniques are arrayed in Table.

 

Table : Converting from Strings to Numerical Values
Target type Code to convert from a String instance (JDK 1.0.2)
int new Integer(String).integerValue()
Integer.valueOf(String).integerValue()
Integer.parseInt(String)
long new Long(String).longValue()
Long.valueOf(String).longValue()
Long.parseLong(String)
float new Float(String).floatValue()
Float.valueOf(String).floatValue()
double new Double(String).doubleValue()
Double.valueOf(String).doubleValue()

     Note: the valueOf methods in Integer and Long can also take a second argument specifying the radix for interpreting the string (e.g., base 8 for octal numbers).
     This picture is expanded considerably in the JDK 1.1. As shown in Table , new classes Short and Byte parallel Integer and Long, and there is an additional decode method in Integer, Short, and Byte (but not Long, curiously):

 

Table : Additional Conversions from String to Number—JDK 1.1
int Integer.decode(String).intValue()
short Short.parseShort(String)
new Short(String).shortValue()
Short.valueOf(String).shortValue()
Short.decode(String).shortValue()
byte Byte.parseByte(String)
new Byte(String).byteValue()
Byte.valueOf(String).byteValue()
Byte.decode(String).byteValue()

The decode methods add the convenience of understanding conventional prefixes such as 0x and # for hexadecimal and 0 for octal.
     All of the above number-parsing expressions throw a NumberFormatException if the String argument does not parse correctly for the desired numerical type. Correct parsing requires that the string is well formed as a number representation and that the value it represents lies within the range covered by the numerical type. The string "128", for instance, fails to parse as a byte. Your code must handle the possible NumberFormatException explicitly, either by catching the exception or declaring it. For example:

     String someString = ...;
     double value;
     try {
         value = Double.valueOf(someString).doubleValue();
     } catch (NumberFormatException e) {
         // ... handle exception
     }
     // ... now use value
     Finally, note that the valueOf and parse<type> methods each have a counterpart taking a second parameter—the radix to use for interpreting the string numerically. For example, the following code parses a long value from a string in hexadecimal format:
     String hexString = "cafebabe";  // cannot have leading 0x
     long value = 0;  // int isn't big enough to hold "cafebabe"
     try {
         value = Long.parseLong(hexString, 16);
     } catch (NumberFormatException e) { /* ... */ }
Q . How do I read a String/int/boolean/etc from the keyboard?


Ans :  

The easiest way is to pick up the source for the 100% pure Java class EasyIn from http://www.afu.com/ (same place as this FAQ). Compile it with your code and use it like this:

EasyIn easy = new EasyIn();

int i = easy.readInt(); // gets an int from System.in
boolean b = easy.readBoolean(); // gets a boolean from System.in
double d = easy.readDouble(); // gets a double from System.in

... etc.

EasyIn is free, comes with source, and you can do what you like with it, including improve it, and send me back the results.

If, instead, you want to "roll your own" code (why?!), in JDK 1.0.2

java.io.DataInputStream in = new java.io.DataInputStream(System.in);
String s = in.readLine();

One way in JDK 1.1:

java.io.BufferedReader in =
new java.io.BufferedReader( new InputStreamReader(System.in));

String s = in.readLine();

Once you have the token in a String, it is easy to parse it into one of the other types, as shown earlier in the FAQ. Yes, it is bone-headed, as it makes the simplest case of keyboard I/O unnecessarily
complicated. A bug was filed with Javasoft to record this problem, but don't count on this being fixed any time soon.

Q . I try to use "int i = System.in.read();" to read in an int from the standard input stream. It doesn't work. Why?

Ans :  

The method read() reads in a single Byte and returns it in int form. System.in is of the class InputStream (the base class of all input streams). InputStream does not provide methods to read int directly. You may want to do this: 

DataInputStream dis = new DataInputStream(System.in);
StringTokenizer st;
...
st = new StringTokenizer(dis.readLine());
int i = Integer.parseInt(st.nextToken());

The method readLine() throws IOException. So, you need to either include the above code in an appropriate try block, or declare the method containing the above code to throw IOException. 

Q . I use the following to read an int. It does not work. Why? 

Ans :  

DataInputStream dis = new DataInputStream(System.in);
int i = dis.readInt();


DataInputStream dis = new DataInputStream(System.in);
int i = dis.readInt();

The method readInt() reads in a 4 Byte int. It does not parse the text to convert to an integer. If you use readInt(), it will read in the next four chars and treat them as an int. To read an int, use the technique described in the answer to the previous question. 

Q . I'm trying to read in a character from a text file using the DataInputStream's readChar() method. However, when I print it out, I get ?'s.

Ans : 

Remember that Java characters are 16-bit Unicode characters, while many hosts systems store characters as 8-bit ASCII characters. Therefore, to read individual chacters from a text file, you need to
ensure the proper conversion. The proper way to do this is to use an InputStreamReader, which converts from 8 to 16 bit streams:

FileInputStream fis = new FileInputStream("myfile.txt");
InputStreamReader isr = new InputStreamReader(fis);
char c3 = (char) isr.read();

The less-favored way (because it is not so portable, as the encodings translation is not done) is just to read a byte and cast it into a character:

FileInputStream fis = new FileInputStream("myfile.txt");
DataInputStream dis = new DataInputStream(fis);
char c1 = (char) dis.readByte();

Q . Why do I get garbage results when I use DataInputStream's readInt or readFloat methods to read in a number from an input string?

Ans :

DataInputStream methods such as readInt and readFloat are not for reading string input—they expect to read a binary representation of the specified numeric type in network byte order (high-end byte first).

     The DataInputStream and DataOutputStream classes are designed primarily for platform-neutral transport of binary data. Invoking DataOutputStream's writeInt method, for example, writes a four-byte binary representation of the int value to the output stream, high-order byte first. Correspondingly, DataInputStream's readInt method takes four bytes from the input stream and combines them into a single int value:

     /* in DataInputStream.java (JDK 1.0.2 and 1.1): */
     public final int readInt() throws IOException {
         InputStream in = this.in;
         int ch1 = in.read();
         int ch2 = in.read();
         int ch3 = in.read();
         int ch4 = in.read();
         if ((ch1 | ch2 | ch3 | ch4) < 0)
              throw new EOFException();
         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
     If you mistakenly try to read a string representation of an integer value using readInt, the first four bytes from that string representation will be converted according to the formula just shown. The result will be systematic, predictable, and almost certainly wrong.
     A simple rule for remembering the purpose of the read... methods in DataInputStream is that they exist to read the output of the corresponding DataOutputStream write... methods. A notable exception to this naming pattern is readLine —its counterpart is writeBytes.
     Note: DataInputStream's readLine method has been deprecated starting with JDK 1.1. Its replacement is the readLine method in class BufferedReader.
Q . How do I read data from a file?

Ans : 

There are a number of ways to read data from a file. If you're reading a file as raw binary data, you open a file using a FileInputStream(String) constructor and use one of the various read() methods to read the data into an array of bytes. For example the following program reads raw data from a file specified on the command line. It then writes the same data to the standard output.

import java.io.*;

class ReadRawData {

    public static void main (String args[]) {
        boolean done = false;
        byte b[] = new byte[1024];
        int num_bytes = 0;

        FileInputStream fin = null;
        try {
              fin = new FileInputStream(args[0]);
        }
        catch(ArrayIndexOutOfBoundsException e) {
             System.out.println("You have to give me the name of a file to open.");
             System.exit(0); 
        }
        catch (FileNotFoundException e) {
             System.out.println("Could not open input file " + args[0]);
             System.exit(0);
      }
      catch(IOException e) {
             System.out.println("Error while opening input file" + args[0]);
             System.exit(0);
      }
      catch (Exception e) {
            System.out.println("Unexpected exception: " + e);
            System.exit(0); 
       }

      try {
         num_bytes = fin.read(b);
      } 
      catch(IOException e) {
          System.out.println("Finished Reading: " + e);
          done = true;
     }
     catch (Exception e) {
          System.out.println("Unexpected exception: " + e);
          System.exit(0); 
     }

    while(!done) {
         System.out.write(b, 0, num_bytes);
         try {
             num_bytes = fin.read(b);
         }
         catch(IOException e) {
             System.out.println("Finished Reading: " + e);
             done = true;
         }
         catch (Exception e) {
            System.out.println("Unexpected exception: " + e);
            System.exit(0); 
        }
       if (num_bytes == -1) done = true;
    } // end while

} // end main

} // end ReadRawData

On the other hand if you're reading a text file in Java 1.0 you'll probably want to use a DataInputStream which gives you a readLine() method that returns successive lines of the file as Java Strings. You can then process each String as you see fit. 

// Implement the Unix cat utility in java

import java.io.*;

class cat {

        public static void main (String args[]) {
            String thisLine;

           //Loop across the arguments
           for (int i=0; i < args.length; i++) {

              //Open the file for reading
              try {
                  FileInputStream fin = new FileInputStream(args[i]);
                  try {
                       DataInputStream myInput = new DataInputStream(fin);

                       try {
                          while ((thisLine = myInput.readLine()) != null) { // while loop begins here
                              System.out.println(thisLine);
                       } // while loop ends here
                   }
                   catch (Exception e) {
                       System.out.println("Error: " + e);
                   }
               } // end try
              catch (Exception e) {
                      System.out.println("Error: " + e);
             }

           } // end try
           catch (Exception e) {
                    System.out.println("failed to open file " + args[i]);
                    System.out.println("Error: " + e);
            }
      } // for ends here

   } // main ends here

}
This code emulates the Unix "cat" command. Given a series of filenames on the command line it concatenates the files onto the standard output. 
In Java 1.1 DataInputStream.readLine() is deprecated. You should use a BufferedReader instead as in this class: 


// Implement the Unix cat utility in java

import java.io.*;

class cat {

      public static void main (String args[]) {

          String thisLine;
           //Loop across the arguments
          for (int i=0; i < args.length; i++) {
             //Open the file for reading
             try {
                  FileReader fr = new FileReader(args[i]); 
                  BufferedReader myInput = new BufferedReader(fr);

                  while ((thisLine = myInput.readLine()) != null) { // while loop begins here
                          System.out.println(thisLine);
                   } // while loop ends here

             } // end try
            catch (IOException e) {
                    System.out.println("Error: " + e);
              }

           } // for ends here

       } // main ends here

}

Q . How do I write data to a file?

Ans : 

You should only assume you'll be able to write to a file from an application. Although it may be possible to write data into a file from an applet if the browser viewing the applet is HotJava, this ability will generally be disabled. From within Netscape there is no way for an applet to write to a file on the local hard drive. 
Within an application, however, file access is straight-forward. There are several ways but here is a simple example using formatted output streams:


import java.io.*;

class PrintToAFile {

       public static void main (String args[]) {

          //First open the file you want to write into
          try {
              FileOutputStream fout = new FileOutputStream("test.out");

              // now convert the FileOutputStream into a PrintStream
              PrintStream myOutput = new PrintStream(fout);

             // Now you're able to use println statements just as if you were using System.out.println
             // to write to the terminal 

               myOutput.println("Hello There!");
               myOutput.println(1 + " + " + 1 + " = " + (1+1));
           }
           catch (IOException e) {
                System.out.println("Error opening file: " + e);
                System.exit(1);
           }

       } // main ends here

}
There are a number of other things to note about writing data to a file. This program creates or opens a file called "test.out" in the same directory as the running program. However you could pass it a full pathname to a file in a different directory instead.
You should also learn about the DataOutputStream class and the write() method when you get a chance. DataOutputStreams and DataInputStreams are used for moving data between Java programs in a portable way. The various incarnations of the write() method are used for writing and reading arbitrary byte streams. What I've demonstrated here is more suitable for human consumption. 

In Java 1.1 you should probably use a PrintWriter instead of a PrintStream.

Q . How do I append data to a file?

Ans : In Java 1.1 you can just pass true as the second argument to this FileOutputStream constructor to indicate that you want to append data to the file:

public FileOutputStream(String name, boolean append) 
throws IOException

In Java 1.0, however, you must use the java.io.RandomAccessFile class that lets you read and write bytes from arbitrary locations in a file. This class implements DataInput and DataOutput so you have all the methods of DataInputStream and DataOutputStream available to you.
To create a new random access file pass the name of the file and the mode to the constructor. The mode is either "r" (read-only) or "rw" (read and write). The length() method returns a long that tells you how many bytes there are in a file and the seek(long p) method lets you position the file pointer at a particular point in the file. Thus to start writing at the end of a RandomAccessFile raf, you first raf.seek(raf.length()). The following example demonstrates by appending the string "Kilroy was here!" to every file specified on the command line.


import java.io.*;

class AppendToAFile {

        public static void main (String args[]) {

            for (int i = 0; i < args.length; i++) {
                //First open the file you want to append to
              try {
                   RandomAccessFile raf = new RandomAccessFile(args[i], "rw");
                   // Position yourself at the end of the file
                   raf.seek(raf.length());

                  // Write the String into the file. Note that you must
                  // explicitly handle line breaks.
                  raf.writeBytes("\nKilroy was here!\n");

               }
               catch (IOException e) {
                   System.out.println("Error opening file: " + e);
               }
          }
      } 
}

Q . When do I need to flush an output stream?

Ans :

Invoke flush on a stream whenever you want your output to be sent to the other end of the output connection (file, remote socket, etc.) as soon as possible.

     Some methods of the input/output system buffer their output and input. In other words, they read or write data in relatively large chunks—usually larger than required by individual method calls—and they keep any excess material in a buffer (temporary storage area) until required to move the data. The flush method in the OutputStream class instructs the system to send any pending material without further delay.
     Besides invoking flush explicitly, you should be aware of flushing that can occur automatically. In the JDK 1.0.2, instances of the PrintStream class can be created with automatic flushing (autoflush) turned on or off. When autoflush is on, the output is flushed whenever a newline occurs in the output stream. Using PrintStream's one-parameter constructor, PrintStream(OutputStream), gives the default: autoflush off. To create a PrintStream instance with autoflush on, use the two-parameter constructor, with a second argument of true:

     OutputStream outStream = ...;
     PrintStream out = new PrintStream(outStream, true);

     In the JDK 1.1, PrintStream is superseded by the PrintWriter class, which provides the same autoflushing controls and defaults. However, a PrintWriter instance does not inherit the autoflushing properties of the underlying output stream it is build on top of. In particular, System.out is a PrintStream instance autoflush set to true, but you must still explicitly set autoflush to true for a PrintWriter instance built on top of System.out:
     PrintWriter writer;
     writer = new PrintWriter(System.out, true);
Q . Why do I see no output when I run a simple process, such as r.exec("/usr/bin/ls")?

Ans  : 

You need to get an input stream from the process, so that output from the process becomes input for your program.

     The Runtime class connects a Java application to the native environment in which the application is running. Among other things, it allows you to start independent processes on the host system, via one of the exec methods. The following code fragment would work on a UNIX system to start a local process that lists the files in the current directory:

     Runtime r = Runtime.getRuntime(); 
     Process p = r.exec("/usr/bin/ls");
     To communicate with a process you've started, you need to hook up the process's standard input and output streams to output and input streams in your Java program. The Process class provides three methods for making such connections, shown in Table 10.3.

 

Table 10.3: Methods for Communicating with a Process Instance
getInputStream() returns an InputStream object for reading from the process's standard output
getOuputStream() returns an OutputStream object for writing to the process's standard input
getErrorStream() returns an InputStream object for reading from the process's standard error output
     Remember that what you call input versus output depends on which side of the connection you view it from: the process's output is your program's input, and your program's output can be the process's input. Also, be aware that if you use the exec method, your program forfeits the cross-platform advantage central to Java technology.
     The following code fragment presents a simple example:
     /* using JDK 1.0.2, on Solaris: */
     Process p;
     Runtime r = Runtime.getRuntime();
     try {
         p = r.exec("/usr/bin/wc");    // UNIX word count program

         /* Send lines of text to the subprocess. */
         out = new PrintStream(p.getOutputStream());
         out.println("This is line 1.");
         out.println("This is line 2.");
         out.println("And this is a somewhat long line 3.");
         out.close();    // important

         /* Read in the output from the subprocess. */
         in = new DataInputStream(p.getInputStream());
         while ((currentLine = in.readLine()) != null) 
             System.out.println(currentLine);
         }
     } catch(IOException e) {
         // ... handle exception
     }
     The corresponding code for the JDK 1.1 uses the same Runtime and Process methods, but wraps appropriate Reader or Writer subclass instances around the underlying byte streams:
     /* using JDK 1.1, in Solaris: */
     Process p;
     Runtime r = Runtime.getRuntime();
     try {
         p = r.exec("/usr/bin/wc");  // UNIX word count program
         PrintWriter outWriter = new PrintWriter(System.out, true);

         /* Send lines of text to the subprocess. */
         writer = new PrintWriter(p.getOutputStream(), true);
         writer.println("This is line 1.");
         writer.println("This is line 2.");
         writer.println("And this is a somewhat long line 3.");
         writer.close();  // important

         /* Read in the output from the subprocess. */
         reader = new BufferedReader(new InputStreamReader(
                                         p.getInputStream()));
         while ((currentLine = reader.readLine()) != null) {
             outWriter.println(currentLine);
         }
     } catch(IOException e) {
         // ... handle exception
     }
Q . Can I write objects to and read objects from a file or other stream?

Ans  : 

In theory yes, but once again all the coding is up to you. There is no general method for doing this in Java 1.0. The problem is made harder by Java's security features that don't let you forge arbitrary byte streams into objects.
In Java 1.1 a serialization interface has been added to the language. However only objects that explicitly implement the java.io.Serializable interface can be serialized. 

Q . How do I format numbers like C's printf()?

Ans : 

Java does not have any built in equivalent to C's printf/sprintf/fprintf family of functions that specify the width and precision of numbers converted into strings. Since Java does not support variable length argument lists, it's not possible to write exact equivalents for these functions. Instead the approach that must be taken is to convert one number at a time into a string according to a format specification, then write the resulting string onto the appropriate output stream. This is a more flexible solution, but it's far from obvious. 
In Java 1.1, the java.text package contains classes that format numbers according to particular needs. In particular it's worth getting to know the java.text.NumberFormat and java.text.DecimalFormat classes, though these can't handle exponential notation. I've begun work on my own formatting class that does handle exponential and other notations available through printf(). It can be found at http://metalab.unc.edu/javafaq/formatter/. Gary Cornell and Cay Horstmann's popular book Core Java also includes such a class. You can probably find more at Gamelan. 

Q . How do I do file I/O in an applet?

Ans :   

By default, an applet can read files on the server, but not write them, and has no access to the client. This is for reasons of security. It would be very unsafe to let any old applet that you downloaded from
an unknown origin on the Internet read/write your files. It would be as unwise as allowing this kind of access to an ActiveX control (which is one reason ActiveX is dead on the Internet).

Q . How do I do I/O to the serial port on my computer?

Ans : 

Java 1.0 and 1.1 do not have a serial port API. There are several commercially-available libraries that supply the needed functionality. JDK 1.2 introduces access to the serial and parallel ports as an
extension (optional extra) library.

Q . How do I do formatted I/O like printf and scanf in C/C++?

Ans : 

The java.text package introduced with Java 1.1 supports formatted I/O.

Q . How do I read a file containing ASCII numbers?

Ans :

There are several ways to do this. Here is one way. Let's assume your file is called "C:\work\mydata.txt" and it contains lines like:

135   7512    3659814   328  1  54829
68522  19982810  38

i.e. lines contain several ASCII strings that are numbers separated by spaces.
The code fragment is as follows:

// Open the file with
RandomAccessFile f = new RandomAccessFile("c:\\work\\datafile.txt", "r");

// read an entire line from it
String s= f.readLine();

// get some methods to break up a line into tokens
StringTokenizer st = new StringTokenizer(s);

// extract the next int from the line
i = Integer.parseInt(st.nextToken());

We use a RandomAccessFile because that supports the readLine() method directly. An alternative would be to instantiate a FileReader, and wrap a BufferedReader around it. Putting it all together, including the exception handling in the event the file is missing, the code lookslike:

import java.io.*;
import java.util.*;
public class c {
     public static void main(String args[]) {
     try {
            RandomAccessFile f = new RandomAccessFile("datafile.txt", "r");
            String s;
            while ( (s=f.readLine()) != null ) {
                     System.out.println("read: "+s);
                     StringTokenizer st = new StringTokenizer(s);
                     int i=0;
                    while (st.hasMoreTokens()) {
                           i = Integer.parseInt(st.nextToken());
                           // i now holds the next int on the line
                           // could also use Double.parseDouble(), etc.
                          System.out.print(" "+ i);
                    }
                    System.out.println();
           }
    } catch (Exception e) {System.out.println("Excpn: "+e); }
              // file I/O, from book "Just Java" by Peter van der Linden
    }
}

Q . Why do I have trouble with System.out.println()?

Ans : 

  "a & b" takes two boolean operands, or two integer operands. It always evaluates both operands. For booleans, it ANDs both operands together producing a boolean result. For integer types, it bitwise ANDs both operands together, producing a result that is the promoted type of the operands (i.e. long, or int). "|" is the corresponding bitwise OR operation. "^" is the corresponding bitwise XOR operation.

"a && b" is a "conditional AND" which only takes boolean operands. It always avoids evaluating its second operand if possible. If a is evaluated to false, the AND result must be "false" and the b operand is not evaluated. This is sometimes called "short-circuited" evaluation. "||" is the corresponding short-circuited OR operation.

Q . How do I write to the serial port on my PC using Java?

Ans : 

There is a platform-independent serial port API introduced in JDK 1.2. You can download the documentation by registering with the Java Developer Connection (it's free, http://java.sun.com) and browsing http://java.sun.com/jdc/earlyAccess/communications.html.

For systems prior to JDK 1.2, read on. At least two companies have written a library to drive the port. See
o http://www.sc-systems.com has a library for Windows 95, WindowsNT, OS/2, Macintosh PPC, Solaris Sparc, Linux x86, FreeBSD x86, HP/UX PA-RISC, and possibly others too.
o http://www.cd.com/portio
o In addition, there is a Unix serial port utility available with source at http://jarvi.ezlink.com/rxtx/ It's free under the GPL, and works on Linux, Irix, Solaris, Windows 95, and NT.

While not helpful to typical home users, there is an alternative portable COM port solution for Java 1.1 and even 1.0. Buy your COM ports in the form of "terminal servers". Using a COM port is now as
easy as connecting to it with a Socket. Port parameters can be changed programatically using SNMP for most terminal servers (but this is never necessary when a modern modem or other fixed-rate equipment is attached). Any networked box can serve as a terminal server - even Win95 - with a simple native server application for that box, but buying an actual firmware based hardware box is much easier.

Furthermore, your Win95 native applications can now share the COM ports (and any attached modems) via a Win95 product called "Dial-out IP" at http://www.tactical-sw.com/.

If the port exists as a pathname in the filesystem, you can open it as a file and read/write. You can also print text this way by writing to "prn" or "lpt1" on a pc, and "/dev/something" on Unix. Writing a
formfeed at the end of the file is essential on Windows 95. Here is some sample code:

// class that opens the printer as a file
// and writes "Hello World" to it

import java.io.*;
public class lpt {
    public static void main (String[] argv) {
    try {
           FileOutputStream os = new FileOutputStream("LPT1");
           //wrap stream in "friendly" PrintStream
           PrintStream ps = new PrintStream(os);

           //print text here
           ps.println("Hello world!");

          //form feed -- this is important
          //Without the form feed, the text will simply sit
          // in print buffer until something else gets printed.
         ps.print("\f");
         //flush buffer and close
         ps.close();
    } catch (Exception e) {
    System.out.println("Exception occurred: " + e);
   }
 }
}

If you wish to change the characteristics of the port (e.g. baud rate, parity, etc.), not just read/write data, Java currently offers no portable way to do this. You will need to use one of the packages mentioned above or some native code or a system command.

Q . Is it possible to lock a file using Java ?

Ans : 

JDK 1.2 introduces the ability to lock a file (indirectly) using the File class. Use createTempFile() with delete on exit. Prior releases of Java do not feature an API to lock a file or regions within
a file. Code that needs to do this must take one of four approaches:
1. Implement an advisory locking scheme using features that Java does have (synchronized methods). This allows you to lock files against use by other Java code running in the same JVM.

2. Use the atomic operation File.createNewFile(), and mark it as deleteOnExit(). Have all processes (Java and non-Java) follow the same protocol: if the create operation succeeded, you have the lock. To give up the lock, you either delete the file or exit the JVM.

Note that this may fail if the file is remotely mounted using NFS version 2. (There's a window of opportunity bewteen the LOOKUP to see if it's already there, and the CREATE if it's not). However,
NFS version 3 does guarantee exclusive create of remotely mounted files, and is not subject to this race condition failure.

3. Make calls to native code to issue the locking ioctls. This approach is not portable, but gives you a shot at having your locks respected by legacy code in non-Java programs using standard locking ioctls.

4. Push the work to a central server. Since socket connection requests arrive in a single queue on the server, this can be used to serialize lock requests. There might be some merit in copying the NFS lockd protocol for a general approach. Rolling your own simple version for a specific application is pretty easy. A database would be better off locking records or fields, not byte offsets. In theory, the server socket approach would make it easier to perform automatic cleanup of a lock on abrupt VM process failure, e.g. by asking "are you still alive?" to the lock holder occasionally.

Q . How do I make the keyboard beep in Java?

Ans : 

In JDK 1.1, java.awt.Toolkit has the method beep(). The pre-1.1 alternative of

System.out.print("\07");
System.out.flush();

(the ASCII BEL character) doesn't work on Macs, but does on some other platforms. Java doesn't support the C abstraction of '\a' for an alert character.

Q . How do I make I/O faster? My file copy program is slow.

Ans : 

This is the purpose of BufferedInputStream. It is a flaw in Java that buffered I/O is not the default, with a flag or different constructor to turn it off. I/O is the second worst designed package in Java, after the Date class. 

Q . How do I do formatted I/O of floating point numbers?

Ans : 

Use the class java.text.NumberFormat.

Or use http://www.newbie.net/sharky/lava/. Or use Cay Horstmann's http://www.horstmann.com/corejava/Format.java Although many utilities claim to handle all varieties of C's printf, as far as has been found, this is the only one to correctly handle the equivalent of %e in printf.

See also the standard packages java.text.DecimalFormat and java.text.NumberFormat

Q . How do I read numbers in exponential format in Java?

Ans : 

The program below (written by Steve Chapel) uses StreamTokenizer to read data from the standard input and recognizes doubles in exponential format (e.g. -1.23e-45).

import java.io.*;

public class ReadExponential {
     public static void main(String argv[]) {
           DataInputStream in = new DataInputStream(System.in);
           StreamTokenizer st = new StreamTokenizer(in);
           try {
               while (st.nextToken() != StreamTokenizer.TT_EOF) {
               switch (st.ttype) {

                    case StreamTokenizer.TT_NUMBER:
                            double num = st.nval;
                            int exp = 0;
                            st.ordinaryChars('\0', ' ');
                            st.nextToken();
                            st.whitespaceChars('\0', ' ');
                            if (st.ttype == StreamTokenizer.TT_WORD &&
                               Character.toUpperCase(st.sval.charAt(0)) == 'E') {
                                try {
                                    exp = Integer.parseInt(st.sval.substring(1));
                                } catch (NumberFormatException e) {
                                     st.pushBack();
                               }
                            } else if (st.ttype < 0 || st.ttype > ' ')
                               st.pushBack();
                               System.out.println("Num " + num * Math.pow(10, exp));
                               break;
                      case StreamTokenizer.TT_WORD:
                              System.out.println("Word " + st.sval);
                              break;
                     default:
                               System.out.println("Char '" + (char) st.ttype + "'");
                               break;
                 } // end switch
         } // end while
      } catch (IOException e) {
              System.out.println("IOException: " + e);
      }
    } // end main
}

Q . How do I delete a directory in Java?

Ans : 

JDK 1.0 did not support directory removal. JDK 1.1 supports directory removal with the method:
public boolean delete() in class java.io.File

Make sure you don't have any open streams in the directory you're trying to remove. Do a close() on all streams, even if the underlying file is gone.

Q . How do I tell how much disk space is free in Java?

Ans : 

There currently aren't any good Java APIs for system introspection. There is no Java way to control processes, or look at system resources. You can use Runtime.getRuntime().exec() to do "df" on unix or "dir" on Windows right now.

Alternatively, check out JConfig:
http://www.tolstoy.com/samizdat/jconfig.html
JConfig is a cross-platform library that fills in many of the gaps in the core Java API, and makes it possible to work with files, processes, file types, video monitors, etc. in a much more Windows- and
Mac-friendly manner.

Q . How do I get a directory listing of the root directory C:\ on a PC?

Ans : 

The obvious approach of calling File.list("C:\"); does not work. There are two reasons why this fails. First, slash is an escape character in Java, so if you want a literal slash, you have to repeat
it. Second, you need to give the name of the directory, i.e. dot. Putting this together, either of the following calls will work

File.list("C:\\.");
or
File.list("C:/.");

Note: a file separator of "/" works just as well as "\" in most Windows programs and library calls. It is an artifact of DOS's origin's as a ripped-off port of CP/M. When Microsoft bought the rights to DOS from
Seattle Computer Products (what, you didn't know Microsoft didn't  develop DOS? They didn't even own the rights to DOS at the time the contracted with IBM to supply DOS for the PC) they were buying software which was an unauthorized port of the CP/M operating system.

CP/M didn't have directories, so it didn't use pathname separators. The forward slash "/" was already used for giving options to CP/M commands, so "\" was pressed into service as the DOS pathname separator, but the DOS shell was taught to understood "/" for compatibility with other OS's.

Q . I did a read from a Buffered stream, and I got fewer bytes than I specified.

Ans : 

This is the way that BufferedInputStream works up to and including the current release. The behavior is so unintuitive that it really represents a bug. Javasoft has "resolved" the bug by writing comments
in the program so that the broken behavior is in the range of legal outcomes. Ugh.

When you instantiate a buffered input stream, you can specify the size of buffer it should use. Let's call this the internal buffer. When you call read() you can say how many bytes to read. Let's call this the
request. If the request is smaller than the internal buffer and not a multiple of the internal buffer, then the last read returns only the odd bytes left in the internal buffer! The more reasonable and intuitive behavior would be for the internal buffer to be refilled, so that the whole request can be granted.

For example, if you create a BufferedInputStream with an internal buffer of 1000 bytes, and try to read 512 byte chunks, your first read will return 512 bytes, but your second read will only return (1000-512), or 488, bytes. (Assuming that the file has at least that many bytes in it). The following code illustrates the problem.

// troubleshooting by Tov Are Jacobsen
import java.io.*;
class filebug {
    public static void main(String args[])
              throws FileNotFoundException, IOException {
         BufferedInputStream bis = new BufferedInputStream(new FileInputStream("test.txt"), 1000 );
         byte[] buf = new byte[2000];
         int numread;
         System.out.println( "Available: "+bis.available() );
         while (true) {
              numread = bis.read(buf,0,512);
              if (numread<0) break;
             System.out.println( "got "+numread+", avail:"+ bis.available());

         }
    }
}

Of course, a valid reason for getting less than you asked for is that you asked for more data than is actually available in the Stream, e.g. you requested 512 bytes from a file that only contains 40 bytes. In
general, there are no guarantees about how much data is returned for a given buffered input stream read request. To avoid this problem, push a DataInputStream on top of your buffered stream. Then you can call readFully(), which will do what you want.

A similar "got less than I asked for" occurs when reading a socket. Network protocols frequently packetize data and send it across in bursts. Nothing is lost of course, and you are always told how many bytes you actually got. You will get the remaining bytes on a subsequent read. This happens regardless of the language used. Be sure to check the "amount of data returned" when using the read(byte[], int, int) method of BufferedInputStream, or when reading from a socket.

Another problem with java.io.InputStream.read(byte[], int, int) is that it catches and ignores IOExceptions. Instead, these exceptions should be passed on to the caller. Ace programmer Jef Poskanzer, jef@acme.com, has a version to do this at http://www.acme.com/java/software/Acme.Utils.html. See Jef's read() and readFully() routines.

Q . How do I redirect the System.err stream to a file?

Ans : 

You cannot assign a new FileOutputStream to System.err, as it is final. Instead use the System.setErr() library call, like this:

FileOutputStream err = new FileOutputStream("stderr.log");
PrintStream errPrintStream = new PrintStream(err);
System.setErr(errPrintStream);

This was introduced with JDK 1.1. There is also a corresponding setIn() for redirecting standard in, and a setOut() for standard out.

Note that you will get a compiler warning about a deprecated construct when you do this. PrintStreams are deprecated in favor of PrintWriters, which handle Unicode properly. The PrintStream is marked as deprecated by marking all its constructors as deprecated. There is no way to create the PrintStream needed to redirect System.err or System.out without triggering the deprecated warning.

Q . What are the values for the Unicode encoding schemes?

Ans : 

The f (or F) suffix directs the compiler to create a float value from a sequence of characters representing a floating point number (a float literal)-otherwise the compiler would by default create either a double value or an int value.

A literal is a string of characters in a source file that the compiler translates directly to a value of a specific type. The Java language recognizes literals for integral numbers, floating point numbers, strings, Unicode characters, boolean values, and null. Table 2.4 shows examples of literals in the Java language, with the types as indicated.

Q . How do I print from a Java program?

Ans :  

Use the Toolkit.getPrintJob() method

Component c = this.getParent();
while (c!=null && !(c instanceof Frame))
c=c.getParent();
 // With a JComponent use c=getTopLevelAncestor();

PrintJob pj = getToolkit().getPrintJob((Frame) c, "test", null);
Graphics pg = pj.getGraphics();
printAll(pg);
pg.dispose();
pj.end();

This feature was introduced with JDK 1.1. A common place to put this is in the code that handles a button press. Printing from an untrusted applet is subject to a check from the SecurityManager.

The JDK 1.1 printing API is more a screen hardcopy facility than a full blown publishing and illustration hardcopy API. JDK 1.2 offers a more full-featured printing API.

If you simply want to print text, then write it to a file and print the file. Or open a filename that corresponds to the printer. On Windows, that is "LPT1" and the code looks like:

try {
    FileOutputStream fos = new FileOutputStream("LPT1");
    PrintStream ps = new PrintStream(fos);
    ps.print("Your string goes here");
    ps.print("\f");
    ps.close();
} catch (Exception e) {
    System.out.println("Exception occurred: " + e);
}

The final formfeed is needed by windows to start the printjob.

Q . What are the properties that can be used in a PrintJob?

Ans : 

The properties are
o awt.print.destination - can be "printer" or "file"
o awt.print.printer - printer name
o awt.print.fileName - name of the file to print
o awt.print.numCopies - obvious
o awt.print.options - options to pass to the print command
o awt.print.orientation - can be "portrait" or "landscape"
o awt.print.paperSize - can be "letter","legal","executive" or "a4"
The defaults are destination=printer, orientation=portrait,
paperSize=letter, and numCopies=1.

You can search for info like this by joining the Java Developer Connection (it's free) at http://java.sun.com/jdc.

and doing a search for "PrintJob".

Q . How do I get Java talking to a Microsoft Access database?

Ans : 

Use the JDBC-ODBC bridge. It is not especially challenging to set up, but it does require painstaking attention to detail. There is a step-by-step example in the van der Linden text "Just Java" mentioned
in the sponsorship section of this document.

Note that the Microsoft version of the Java kit does not support JDBC-ODBC access because it uses a non-standard native code interface. The JDBC FAQ can be found at http://java.sun.com/products/jdbc/jdbc-frequent.html 

Q . How do I do I/O redirection in Java using exec()?

Ans : 

This solution works on Unix platforms using either JDK 1.0.2, or JDK 1.1. The trick is to use an array of Strings for the command line:

String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};

If you don't do this, and simply use a single string, the shell will see the -c and /bin/ls and ignore everything else after that. It only expects a single argument after the -c.

import java.io.*;
import java.util.*;

class IoRedirect {
   public static void main(String Argv[]) {
   try {
        String[] command = {"/bin/sh", "-c", "/bin/ls > out.dat"};
        Process p = Runtime.getRuntime().exec(command);
        p.waitFor();
        System.out.println("return code: "+ p.exitValue());
   } catch (IOException e) {
       System.err.println("IO error: " + e);
   } catch (InterruptedException e1) {
        System.err.println("Exception: " + e1.getMessage());
   }
  }
}

 

Copyright © 2000 javafaq.com. All rights reserved