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 else {
141 initFileInputStream();
142
143 return fileInputStream.read(bytes, offset, length);
144 }
145 }
146
147 @Override
148 public void reset() throws IOException {
149 if (data != null) {
150 index = markIndex;
151 }
152 else if (fileInputStream != null) {
153 fileInputStream.close();
154
155 fileInputStream = null;
156 }
157 }
158
159 @Override
160 public long skip(long skip) throws IOException {
161 if (skip < 0) {
162 return 0;
163 }
164
165 if (fileSize < threshold) {
166 initData();
167
168 if ((skip + index) > data.length) {
169 skip = data.length - index;
170 }
171
172 index += skip;
173
174 return skip;
175 }
176 else {
177 initFileInputStream();
178
179 return fileInputStream.skip(skip);
180 }
181 }
182
183 protected void initData() throws IOException {
184 if (data != null) {
185 return;
186 }
187
188 int arraySize = (int)this.fileSize;
189
190 data = new byte[arraySize];
191
192 FileInputStream fileInputStream = new FileInputStream(file);
193
194 int offset = 0;
195 int length = 0;
196
197 try {
198 while (offset < arraySize) {
199 length = fileInputStream.read(data, offset, arraySize - offset);
200
201 offset += length;
202 }
203 }
204 finally {
205 fileInputStream.close();
206 }
207 }
208
209 protected void initFileInputStream() throws IOException {
210 if (fileInputStream == null) {
211 fileInputStream = new FileInputStream(file);
212 }
213 }
214
215 protected byte[] data;
216 protected boolean deleteOnClose;
217 protected File file;
218 protected FileInputStream fileInputStream;
219 protected long fileSize;
220 protected int index;
221 protected int markIndex;
222 protected int threshold;
223
224 }