Java Read File One Character at a Time

Introduction to File Input and Output

(with illustrations from The Java Tutorial)

Nosotros have seen in this class how objects communicate with each other. Plan often need to communicate with the outside world. The means of communication are input (such as a keyboard) and output (such as the computer screen). Programs tin too communicate through stored data, such as files.

I/O Streams

A stream is a communication aqueduct that a plan has with the outside world. Information technology is used to transfer data items in succession.

An Input/Output (I/O) Stream represents an input source or an output destination. A stream can represent many different kinds of sources and destinations, including disk files, devices, other programs, and memory arrays.

Streams support many different kinds of data, including simple bytes, archaic data types, localized characters, and objects. Some streams simply pass on data; others manipulate and transform the data in useful means.

No matter how they work internally, all streams nowadays the aforementioned simple model to programs that use them: A stream is a sequence of data.

Reading information into a plan.

A plan uses an input stream to read data from a source, i detail at a fourth dimension:

Reading information into a program.

Writing information from a programme.

A program uses an output stream to write information to a destination, one particular at time:

Writing information from a program.

The data source and data destination pictured above tin exist anything that holds, generates, or consumes information. Obviously this includes disk files, just a source or destination can also another program, a peripheral device, a network socket, or an array.

The Coffee IO API

The java.io bundle contains many classes that your programs tin use to read and write data. Most of the classes implement sequential access streams. The sequential access streams can be divided into 2 groups: those that read and write bytes and those that read and write Unicode characters. Each sequential access stream has a speciality, such every bit reading from or writing to a file, filtering data equally its read or written, or serializing an object.

Types of Streams

Byte Streams: Byte streams perform input and output of 8-flake bytes. They read and write data one byte at a time. Using byte streams is the lowest level of I/0, so if you are reading or writing graphic symbol data the best approach is to use character streams. Other stream types are built on top of byte streams.

Graphic symbol Streams: All character stream classes are descended from Reader and Writer.We are going to utilize the Reader and Author classes that perform file I/0, FileReader and FileWriter. We will look at two examples of writing programs using character streams, one that reads and writes 1 character at a time and one that reads and writes one line at a time.

For sample input, nosotros'll use the example file xanadu.txt, which contains the following verse:

In Xanadu did Kubla Khan A stately pleasure-dome decree: Where Alph, the sacred river, ran Through caverns measureless to man Downwardly to a sunless ocean.        

Example i: Reading and Writing One Graphic symbol at a fourth dimension

Hither is an case of a plan that copies a file one character at a time. The IOTest class has a copyCharacters method which creates an example of FileReader and passes the proper noun of the file to exist read to the FileReader constructor. It then creates an instance of FileWriter and passes the name of the file to be written to the FileWriter constructor.

It and so copies the contents of the xanadu.txt file to the characteroutput.txt file, character by grapheme.

It uses an int variable, "c", to read to and write from. The int variable holds a grapheme value. Using an int as the return type allows read() to apply -1 to indicate that information technology has reached the terminate of the stream.

Notice that at that place is a block of code preceded by the keyword attempt and another cake of code preceded by the keyword finally. This is to ensure that the lawmaking in the finally block gets executed, fifty-fifty if the code within the try block causes an exception to exist thrown (e.g. if you try to open a file for which you lot don't have permission). Don't worry if you don't understand it completely; you can re-create and paste our examples in to your programs.

import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;     public class IOTest {        public static void copyCharacters() throws IOException {         FileReader inputStream = nix;         FileWriter outputStream = null;          endeavour {             inputStream = new FileReader("xanadu.txt");             outputStream = new FileWriter("xanadu_output.txt");              int c;             while ((c = inputStream.read()) != -1) {                 outputStream.write(c);             }         } finally {             if (inputStream != null) {                 inputStream.close();             }             if (outputStream != nil) {                 outputStream.shut();             }         }     }  }        

Always Close Streams

Closing a stream when it's no longer needed is very of import. That is why CopyCharacters uses a finally cake to guarantee that both streams will be closed even if an error occurs. This practice helps avoid serious resources leaks.

I possible error is that CopyCharacters was unable to open one or both files. When that happens, the stream variable corresponding to the file never changes from its initial nothing value. That'due south why CopyCharacters makes sure that each stream variable contains an object reference earlier invoking shut.

Example 2: Reading and Writing ane line a a time

Character I/O is normally candy in units longer than single characters. One common unit of measurement is the line: a cord of characters with a line terminator at the end. A line terminator can be a carriage-return/line-feed sequence ("\r\due north"), a single carriage-return ("\r"), or a single line-feed ("\n"). Supporting all possible line terminators allows programs to read text files created on any of the widely used operating systems.

Let's change the copyCharacters example to utilise line-oriented I/O. To do this, nosotros have to use two classes we haven't seen before, BufferedReader and PrintWriter.

The copyLines method example invokes BufferedReader.readLine and PrintWriter.println to do input and output ane line at a time.

import java.io.FileReader; import java.io.FileWriter; import java.io.BufferedReader; import java.io.PrintWriter; import java.io.IOException;      public static void copyLines() throws IOException {         BufferedReader inputStream = zilch;         PrintWriter outputStream = zip;          endeavor {             inputStream =                  new BufferedReader(new FileReader("xanadu.txt"));             outputStream =                  new PrintWriter(new FileWriter("characteroutput.txt"));              String l;             while ((l = inputStream.readLine()) != naught) {                 outputStream.println(l);             }         } finally {             if (inputStream != goose egg) {                 inputStream.close();             }             if (outputStream != nix) {                 outputStream.shut();             }         }     }        

Invoking readLine returns a line of text. This line is then output using PrintWriter'southward println method, which appends the line terminator for the current operating system. This might non be the same line terminator that was used in the input file.

Scanning

The Scanner course is available in Coffee v (JDK 1.5). It provides methods to convert text into appropriate Java types (integer, bladder, etc). A scanner splits text into a succession of tokens (text representations of data values) according to specific rules.

For example, in the String object "ab*cd 12.34 253", "ab*cd" is a String token, "12.34" is a double token and "253" is an integer token.

Objects of type Scanner are useful for breaking downwards formatted input into tokens and translating individual tokens co-ordinate to their information type.

Selected Constructors:

  • public Scanner(String s): Constructs a new Scanner that produces values scanned from the specified cord.
  • public Scanner(InputStream source): Constructs a new Scanner that produces values scanned from the specif

Selected Methods:

  • public Cord nextLine(): Browse the next line of input
  • public int nextInt(): Scan the next integer
  • public double nextDouble(): Browse the side by side double

See the Scanner API documentation for more methods.

Scanner Instance i

By default, a scanner uses white infinite to separate tokens. (White space characters include blanks, tabs, and line terminators. For the full list, refer to the documentation for Character.isWhitespace.) To see how scanning works, let's expect at ScanXan, a programme that reads the individual words in xanadu.txt and prints them out, one per line.

import java.io.*; import coffee.util.Scanner;   public class ScanXan {     public static void main(Cord[] args) throws IOException {         Scanner s = nothing;         effort {             due south = new Scanner(new BufferedReader(new FileReader("xanadu.txt")));              while (s.hasNext()) {                 Organisation.out.println(southward.next());             }         } finally {             if (s != null) {                 due south.close();             }         }     } }        

Notice that ScanXan invokes Scanner's shut method when it is washed with the scanner object. Even though a scanner is not a stream, you lot need to close it to signal that you're done with its underlying stream.

The output of ScanXan looks like this:

In Xanadu did Kubla Khan A stately pleasure-dome ...      

To use a dissimilar token separator, invoke useDelimiter(), specifying a regular expression. For example, suppose y'all wanted the token separator to be a comma, optionally followed past white space. You would invoke, s.useDelimiter(",\\south*");

Scanner Example 2: Translating Individual Tokens

The ScanXan case treats all input tokens as simple Cord values. Scanner besides supports tokens for all of the Java language'due south primitive types (except for char), as well as BigInteger and BigDecimal. Also, numeric values can use thousands separators. Thus, Scanner correctly reads the string "32,767" as representing an integer value.

The ScanSum example reads a listing of double values and adds them upwards.

import java.io.FileReader; import coffee.io.BufferedReader; import java.io.IOException; import java.util.Scanner; import java.util.Locale;   public course ScanSum {     public static void main(Cord[] args) throws IOException {         Scanner due south = null;         double sum = 0;         try {             s = new Scanner(                     new BufferedReader(new FileReader("usnumbers.txt")));                          while (south.hasNext()) {                 if (s.hasNextDouble()) {                         sum += south.nextDouble();                     } else {                         s.next();                     }                }         } finally {             south.close();         }          Organization.out.println(sum);     } }        
And here's the sample input file, usnumbers.txt,
eight.five 832,767 83.14159 81,000,000.1        

The output string is "1032778.74159".


stamperbubtroge42.blogspot.com

Source: https://www.seas.upenn.edu/~cis1xx/resources/java/fileIO/introToFileIO.html

0 Response to "Java Read File One Character at a Time"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel