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