• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.io;
19 
20 import java.nio.CharBuffer;
21 import java.nio.ReadOnlyBufferException;
22 
23 /*** The base class for all readers. A reader is a means of reading data from a source in a character-wise manner. Some readers also
24  * support marking a position in the input and returning to this position later.
25  * <p>
26  * This abstract class does not provide a fully working implementation, so it needs to be subclassed, and at least the
27  * {@link #read(char[], int, int)} and {@link #close()} methods needs to be overridden. Overriding some of the non-abstract
28  * methods is also often advised, since it might result in higher efficiency.
29  * <p>
30  * Many specialized readers for purposes like reading from a file already exist in this package.
31  *
32  * @see Writer */
33 public abstract class Reader implements Readable, Closeable {
34 	/*** The object used to synchronize access to the reader. */
35 	protected Object lock;
36 
37 	/*** Constructs a new {@code Reader} with {@code this} as the object used to synchronize critical sections. */
Reader()38 	protected Reader () {
39 		super();
40 		lock = this;
41 	}
42 
43 	/*** Constructs a new {@code Reader} with {@code lock} used to synchronize critical sections.
44 	 *
45 	 * @param lock the {@code Object} used to synchronize critical sections.
46 	 * @throws NullPointerException if {@code lock} is {@code null}. */
Reader(Object lock)47 	protected Reader (Object lock) {
48 		if (lock == null) {
49 			throw new NullPointerException();
50 		}
51 		this.lock = lock;
52 	}
53 
54 	/*** Closes this reader. Implementations of this method should free any resources associated with the reader.
55 	 *
56 	 * @throws IOException if an error occurs while closing this reader. */
close()57 	public abstract void close () throws IOException;
58 
59 	/*** Sets a mark position in this reader. The parameter {@code readLimit} indicates how many characters can be read before the
60 	 * mark is invalidated. Calling {@code reset()} will reposition the reader back to the marked position if {@code readLimit} has
61 	 * not been surpassed.
62 	 * <p>
63 	 * This default implementation simply throws an {@code IOException}; subclasses must provide their own implementation.
64 	 *
65 	 * @param readLimit the number of characters that can be read before the mark is invalidated.
66 	 * @throws IllegalArgumentException if {@code readLimit < 0}.
67 	 * @throws IOException if an error occurs while setting a mark in this reader.
68 	 * @see #markSupported()
69 	 * @see #reset() */
mark(int readLimit)70 	public void mark (int readLimit) throws IOException {
71 		throw new IOException();
72 	}
73 
74 	/*** Indicates whether this reader supports the {@code mark()} and {@code reset()} methods. This default implementation returns
75 	 * {@code false}.
76 	 *
77 	 * @return always {@code false}. */
markSupported()78 	public boolean markSupported () {
79 		return false;
80 	}
81 
82 	/*** Reads a single character from this reader and returns it as an integer with the two higher-order bytes set to 0. Returns -1
83 	 * if the end of the reader has been reached.
84 	 *
85 	 * @return the character read or -1 if the end of the reader has been reached.
86 	 * @throws IOException if this reader is closed or some other I/O error occurs. */
read()87 	public int read () throws IOException {
88 		synchronized (lock) {
89 			char charArray[] = new char[1];
90 			if (read(charArray, 0, 1) != -1) {
91 				return charArray[0];
92 			}
93 			return -1;
94 		}
95 	}
96 
97 	/*** Reads characters from this reader and stores them in the character array {@code buf} starting at offset 0. Returns the
98 	 * number of characters actually read or -1 if the end of the reader has been reached.
99 	 *
100 	 * @param buf character array to store the characters read.
101 	 * @return the number of characters read or -1 if the end of the reader has been reached.
102 	 * @throws IOException if this reader is closed or some other I/O error occurs. */
read(char buf[])103 	public int read (char buf[]) throws IOException {
104 		return read(buf, 0, buf.length);
105 	}
106 
107 	/*** Reads at most {@code count} characters from this reader and stores them at {@code offset} in the character array {@code buf}
108 	 * . Returns the number of characters actually read or -1 if the end of the reader has been reached.
109 	 *
110 	 * @param buf the character array to store the characters read.
111 	 * @param offset the initial position in {@code buffer} to store the characters read from this reader.
112 	 * @param count the maximum number of characters to read.
113 	 * @return the number of characters read or -1 if the end of the reader has been reached.
114 	 * @throws IOException if this reader is closed or some other I/O error occurs. */
read(char buf[], int offset, int count)115 	public abstract int read (char buf[], int offset, int count) throws IOException;
116 
117 	/*** Indicates whether this reader is ready to be read without blocking. Returns {@code true} if this reader will not block when
118 	 * {@code read} is called, {@code false} if unknown or blocking will occur. This default implementation always returns
119 	 * {@code false}.
120 	 *
121 	 * @return always {@code false}.
122 	 * @throws IOException if this reader is closed or some other I/O error occurs.
123 	 * @see #read()
124 	 * @see #read(char[])
125 	 * @see #read(char[], int, int) */
ready()126 	public boolean ready () throws IOException {
127 		return false;
128 	}
129 
130 	/*** Resets this reader's position to the last {@code mark()} location. Invocations of {@code read()} and {@code skip()} will
131 	 * occur from this new location. If this reader has not been marked, the behavior of {@code reset()} is implementation
132 	 * specific. This default implementation throws an {@code IOException}.
133 	 *
134 	 * @throws IOException always thrown in this default implementation.
135 	 * @see #mark(int)
136 	 * @see #markSupported() */
reset()137 	public void reset () throws IOException {
138 		throw new IOException();
139 	}
140 
141 	/*** Skips {@code amount} characters in this reader. Subsequent calls of {@code read} methods will not return these characters
142 	 * unless {@code reset()} is used. This method may perform multiple reads to read {@code count} characters.
143 	 *
144 	 * @param count the maximum number of characters to skip.
145 	 * @return the number of characters actually skipped.
146 	 * @throws IllegalArgumentException if {@code amount < 0}.
147 	 * @throws IOException if this reader is closed or some other I/O error occurs.
148 	 * @see #mark(int)
149 	 * @see #markSupported()
150 	 * @see #reset() */
skip(long count)151 	public long skip (long count) throws IOException {
152 		if (count < 0) {
153 			throw new IllegalArgumentException();
154 		}
155 		synchronized (lock) {
156 			long skipped = 0;
157 			int toRead = count < 512 ? (int)count : 512;
158 			char charsSkipped[] = new char[toRead];
159 			while (skipped < count) {
160 				int read = read(charsSkipped, 0, toRead);
161 				if (read == -1) {
162 					return skipped;
163 				}
164 				skipped += read;
165 				if (read < toRead) {
166 					return skipped;
167 				}
168 				if (count - skipped < toRead) {
169 					toRead = (int)(count - skipped);
170 				}
171 			}
172 			return skipped;
173 		}
174 	}
175 
176 	/*** Reads characters and puts them into the {@code target} character buffer.
177 	 *
178 	 * @param target the destination character buffer.
179 	 * @return the number of characters put into {@code target} or -1 if the end of this reader has been reached before a character
180 	 *         has been read.
181 	 * @throws IOException if any I/O error occurs while reading from this reader.
182 	 * @throws NullPointerException if {@code target} is {@code null}.
183 	 * @throws ReadOnlyBufferException if {@code target} is read-only. */
184 	public int read (CharBuffer target) throws IOException {
185 		if (null == target) {
186 			throw new NullPointerException();
187 		}
188 		int length = target.length();
189 		char[] buf = new char[length];
190 		length = Math.min(length, read(buf));
191 		if (length > 0) {
192 			target.put(buf, 0, length);
193 		}
194 		return length;
195 	}
196 }
197