001
014
015 package com.liferay.portal.kernel.io;
016
017 import java.io.File;
018 import java.io.FileInputStream;
019 import java.io.IOException;
020 import java.io.InputStream;
021
022
025 public class ByteArrayFileInputStream extends InputStream {
026
027 public ByteArrayFileInputStream(File file, int threshold) {
028 this(file, threshold, false);
029 }
030
031 public ByteArrayFileInputStream(
032 File file, int threshold, boolean deleteOnClose) {
033
034 if (!file.exists() || !file.isFile()) {
035 throw new IllegalArgumentException(
036 "File " + file.getAbsolutePath() + " does not exist");
037 }
038
039 this.file = file;
040 fileSize = file.length();
041 this.threshold = threshold;
042 this.deleteOnClose = deleteOnClose;
043 }
044
045 @Override
046 public int available() throws IOException {
047 if (data != null) {
048 return data.length - index;
049 }
050 else if (fileInputStream != null) {
051 return fileInputStream.available();
052 }
053 else {
054 return 0;
055 }
056 }
057
058 @Override
059 public void close() throws IOException {
060 try {
061 if (fileInputStream != null) {
062 fileInputStream.close();
063 }
064 }
065 finally {
066 data = null;
067 fileInputStream = null;
068
069 if (deleteOnClose) {
070 file.delete();
071 }
072
073 file = null;
074 }
075 }
076
077 public File getFile() {
078 return file;
079 }
080
081 @Override
082 public void mark(int readLimit) {
083 markIndex = index;
084 }
085
086 @Override
087 public boolean markSupported() {
088 return fileSize < threshold;
089 }
090
091 @Override
092 public int read() throws IOException {
093 if (fileSize < threshold) {
094 initData();
095
096 if (index < data.length) {
097 return data[index++] & 0xff;
098 }
099 else {
100 return -1;
101 }
102 }
103 else {
104 initFileInputStream();
105
106 return fileInputStream.read();
107 }
108 }
109
110 @Override
111 public int read(byte[] bytes) throws IOException {
112 return read(bytes, 0, bytes.length);
113 }
114
115 @Override
116 public int read(byte[] bytes, int offset, int length) throws IOException {
117 if (length <= 0) {
118 return 0;
119 }
120
121 if (fileSize < threshold) {
122 initData();
123
124 if (index >= data.length) {
125 return -1;
126 }
127
128 int read = length;
129
130 if ((index + read) > data.length) {
131 read = data.length - index;
132 }
133
134 System.arraycopy(data, index, bytes, offset, read);
135
136 index += read;
137
138 return read;
139 }
140
141 initFileInputStream();
142
143 return fileInputStream.read(bytes, offset, length);
144 }
145
146 @Override
147 public void reset() throws IOException {
148 if (data != null) {
149 index = markIndex;
150 }
151 else if (fileInputStream != null) {
152 fileInputStream.close();
153
154 fileInputStream = null;
155 }
156 }
157
158 @Override
159 public long skip(long skip) throws IOException {
160 if (skip < 0) {
161 return 0;
162 }
163
164 if (fileSize < threshold) {
165 initData();
166
167 if ((skip + index) > data.length) {
168 skip = data.length - index;
169 }
170
171 index += skip;
172
173 return skip;
174 }
175
176 initFileInputStream();
177
178 return fileInputStream.skip(skip);
179 }
180
181 protected void initData() throws IOException {
182 if (data != null) {
183 return;
184 }
185
186 int arraySize = (int)this.fileSize;
187
188 data = new byte[arraySize];
189
190 FileInputStream fileInputStream = new FileInputStream(file);
191
192 int offset = 0;
193 int length = 0;
194
195 try {
196 while (offset < arraySize) {
197 length = fileInputStream.read(data, offset, arraySize - offset);
198
199 offset += length;
200 }
201 }
202 finally {
203 fileInputStream.close();
204 }
205 }
206
207 protected void initFileInputStream() throws IOException {
208 if (fileInputStream == null) {
209 fileInputStream = new FileInputStream(file);
210 }
211 }
212
213 protected byte[] data;
214 protected boolean deleteOnClose;
215 protected File file;
216 protected FileInputStream fileInputStream;
217 protected long fileSize;
218 protected int index;
219 protected int markIndex;
220 protected int threshold;
221
222 }