1+ /**
2+ * Licensed to the Apache Software Foundation (ASF) under one
3+ * or more contributor license agreements. See the NOTICE file
4+ * distributed with this work for additional information
5+ * regarding copyright ownership. The ASF licenses this file
6+ * to you under the Apache License, Version 2.0 (the
7+ * "License"); you may not use this file except in compliance
8+ * with the License. You may obtain a copy of the License at
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing, software
13+ * distributed under the License is distributed on an "AS IS" BASIS,
14+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+ * See the License for the specific language governing permissions and
16+ * limitations under the License.
17+ */
18+
19+ package org .apache .hadoop .io ;
20+
21+ import org .apache .hadoop .util .Shell ;
22+
23+ import java .io .InputStream ;
24+ import java .io .FileInputStream ;
25+ import java .io .File ;
26+ import java .io .FileDescriptor ;
27+ import java .io .IOException ;
28+ import java .io .RandomAccessFile ;
29+
30+ import java .nio .channels .Channels ;
31+ import java .nio .channels .FileChannel ;
32+
33+ /**
34+ * This class is substitute FileInputStream. When on windows, We are still use
35+ * FileInputStream. For non-windows, we use channel and FileDescriptor to
36+ * construct a stream.
37+ */
38+ public class AltFileInputStream extends InputStream {
39+ // For non-Windows
40+ private final InputStream inputStream ;
41+ private final FileDescriptor fd ;
42+ private final FileChannel fileChannel ;
43+
44+ // For Windows
45+ private FileInputStream fileInputStream ;
46+
47+ public AltFileInputStream (File file ) throws IOException {
48+ if (!Shell .WINDOWS ) {
49+ RandomAccessFile rf = new RandomAccessFile (file , "r" );
50+ this .fd = rf .getFD ();
51+ this .fileChannel = rf .getChannel ();
52+ this .inputStream = Channels .newInputStream (fileChannel );
53+ } else {
54+ FileInputStream fis = new FileInputStream (file );
55+ this .fileInputStream = fis ;
56+ this .inputStream = fileInputStream ;
57+ this .fd = fis .getFD ();
58+ this .fileChannel = fis .getChannel ();
59+ }
60+ }
61+
62+ /**
63+ * Create a stream with fd and channel
64+ * @param fd FileDescriptor
65+ * @param fileChannel FileChannel
66+ */
67+ public AltFileInputStream (FileDescriptor fd , FileChannel fileChannel ) {
68+ this .fd = fd ;
69+ this .fileChannel = fileChannel ;
70+ this .inputStream = Channels .newInputStream (fileChannel );
71+ }
72+
73+ /**
74+ * Create a stream with FileInputSteam
75+ * @param fis FileInputStream
76+ * @throws IOException
77+ */
78+ public AltFileInputStream (FileInputStream fis ) throws IOException {
79+ this .fileInputStream = fis ;
80+ this .inputStream = fileInputStream ;
81+ this .fd = fis .getFD ();
82+ this .fileChannel = fis .getChannel ();
83+ }
84+
85+ /**
86+ * Returns the <code>FileDescriptor</code>
87+ * object that represents the connection to
88+ * the actual file in the file system being
89+ * used by this <code>FileInputStream</code>.
90+ *
91+ * @return the file descriptor object associated with this stream.
92+ * @exception IOException if an I/O error occurs.
93+ * @see java.io.FileDescriptor
94+ */
95+ public final FileDescriptor getFD () throws IOException {
96+ if (fd != null ) {
97+ return fd ;
98+ }
99+ throw new IOException ();
100+ }
101+
102+ // return a channel
103+ public FileChannel getChannel () {
104+ return fileChannel ;
105+ }
106+
107+ /**
108+ * For Windows, use fileInputStream to read data.
109+ * For Non-Windows, use inputStream to read data.
110+ * @return
111+ * @throws IOException
112+ */
113+ public int read () throws IOException {
114+ if (fileInputStream != null ) {
115+ return fileInputStream .read ();
116+ } else {
117+ return inputStream .read ();
118+ }
119+ }
120+
121+ /**
122+ * Reads up to <code>len</code> bytes of data from this input stream
123+ * into an array of bytes. If <code>len</code> is not zero, the method
124+ * blocks until some input is available; otherwise, no
125+ * bytes are read and <code>0</code> is returned.
126+ *
127+ * @param b the buffer into which the data is read.
128+ * @param off the start offset in the destination array <code>b</code>
129+ * @param len the maximum number of bytes read.
130+ * @return the total number of bytes read into the buffer, or
131+ * <code>-1</code> if there is no more data because the end of
132+ * the file has been reached.
133+ * @exception NullPointerException If <code>b</code> is <code>null</code>.
134+ * @exception IndexOutOfBoundsException If <code>off</code> is negative,
135+ * <code>len</code> is negative, or <code>len</code> is greater than
136+ * <code>b.length - off</code>
137+ * @exception IOException if an I/O error occurs.
138+ */
139+ public int read (byte [] b , int off , int len ) throws IOException {
140+ if (fileInputStream != null ) {
141+ return fileInputStream .read (b , off , len );
142+ } else {
143+ return inputStream .read (b , off , len );
144+ }
145+ }
146+
147+ /**
148+ * Reads up to <code>b.length</code> bytes of data from this input
149+ * stream into an array of bytes. This method blocks until some input
150+ * is available.
151+ *
152+ * @param b the buffer into which the data is read.
153+ * @return the total number of bytes read into the buffer, or
154+ * <code>-1</code> if there is no more data because the end of
155+ * the file has been reached.
156+ * @exception IOException if an I/O error occurs.
157+ */
158+ public int read (byte [] b ) throws IOException {
159+ if (fileInputStream != null ) {
160+ return fileInputStream .read (b );
161+ } else {
162+ return inputStream .read (b );
163+ }
164+ }
165+
166+ /**
167+ * Closes this file input stream and releases any system resources
168+ * associated with the stream.
169+ *
170+ * <p> If this stream has an associated channel then the channel is closed
171+ * as well.
172+ *
173+ * @exception IOException if an I/O error occurs.
174+ */
175+ public void close () throws IOException {
176+ if (fileInputStream != null ) {
177+ fileInputStream .close ();
178+ }
179+ fileChannel .close ();
180+ inputStream .close ();
181+ }
182+ }
0 commit comments