• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 package com.ohos.hapsigntool.utils;
17 
18 import com.google.gson.Gson;
19 import com.google.gson.GsonBuilder;
20 import com.ohos.hapsigntool.error.ERROR;
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
23 
24 import java.io.BufferedWriter;
25 import java.io.ByteArrayOutputStream;
26 import java.io.Closeable;
27 import java.io.DataOutputStream;
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.FileNotFoundException;
31 import java.io.FileOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35 import java.io.OutputStreamWriter;
36 import java.nio.charset.Charset;
37 
38 /**
39  * Common file operation.
40  *
41  * @since 2021/12/28
42  */
43 public final class FileUtils {
44 
45     /**
46      * LOGGER.
47      */
48     private static final Logger LOGGER = LogManager.getLogger(FileUtils.class);
49     /**
50      * add GSON static.
51      */
52     public static final Gson GSON = (new GsonBuilder()).disableHtmlEscaping().create();
53     /**
54      * add GSON_PRETTY_PRINT static.
55      */
56     public static final Gson GSON_PRETTY_PRINT = (new GsonBuilder()).disableHtmlEscaping().setPrettyPrinting().create();
57     /**
58      * File reader block size
59      */
60     public static final int FILE_BUFFER_BLOCK = 4096;
61     /**
62      * File end
63      */
64     public static final int FILE_END = -1;
65     /**
66      * Expected split string length
67      */
68     public static final int SPLIT_LENGTH = 2;
69 
70     private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
71 
FileUtils()72     private FileUtils() {
73     }
74 
75     /**
76      * Close closeable quietly.
77      *
78      * @param closeable closeable
79      */
close(Closeable closeable)80     public static void close(Closeable closeable) {
81         if (closeable != null) {
82             try {
83                 closeable.close();
84             } catch (IOException exception) {
85                 LOGGER.debug(exception.getMessage(), exception);
86             }
87         }
88     }
89 
90     /**
91      * Read byte from input file.
92      *
93      * @param file Which file to read
94      * @return byte content
95      * @throws IOException Read failed
96      */
readFile(File file)97     public static byte[] readFile(File file) throws IOException {
98         return read(new FileInputStream(file));
99     }
100 
101     /**
102      * Read byte from input stream.
103      *
104      * @param input Input stream
105      * @return File content
106      * @throws IOException Read failed
107      */
read(InputStream input)108     public static byte[] read(InputStream input) throws IOException {
109         try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
110             byte[] buffer = new byte[FILE_BUFFER_BLOCK];
111             int read;
112             while ((read = input.read(buffer)) != FILE_END) {
113                 output.write(buffer, 0, read);
114             }
115             return output.toByteArray();
116         } finally {
117             close(input);
118         }
119     }
120 
121     /**
122      * Out put content to file.
123      *
124      * @param content Which content to out put
125      * @param output  File to write
126      * @throws IOException Write failed
127      */
write(byte[] content, File output)128     public static void write(byte[] content, File output) throws IOException {
129         try (FileOutputStream out = new FileOutputStream(output)) {
130             for (byte con : content) {
131                 out.write(con);
132             }
133         }
134     }
135 
136     /**
137      * Check file exist or not.
138      *
139      * @param filePath File path
140      * @return Is file exist
141      */
isFileExist(String filePath)142     public static boolean isFileExist(String filePath) {
143         return new File(filePath).exists();
144     }
145 
146     /**
147      * Throw runtime exception if not allowed file type.
148      *
149      * @param filePath file path
150      * @param types    Such as "txt" "json" "mp3"
151      */
validFileType(String filePath, String... types)152     public static void validFileType(String filePath, String... types) {
153         String suffix = getSuffix(filePath);
154         ValidateUtils.throwIfNotMatches(!StringUtils.isEmpty(suffix),
155                 ERROR.NOT_SUPPORT_ERROR, "Not support file: " + filePath);
156         boolean isMatches = false;
157         for (String type : types) {
158             if (StringUtils.isEmpty(type)) {
159                 continue;
160             }
161             if (type.equalsIgnoreCase(suffix)) {
162                 isMatches = true;
163                 break;
164             }
165         }
166         ValidateUtils.throwIfNotMatches(isMatches, ERROR.NOT_SUPPORT_ERROR, "Not support file: " + filePath);
167     }
168 
169     /**
170      * Get suffix of file.
171      *
172      * @param filePath file path
173      * @return file suffix. Such as "txt" "json" "p12"
174      */
getSuffix(String filePath)175     public static String getSuffix(String filePath) {
176         if (StringUtils.isEmpty(filePath)) {
177             return "";
178         }
179         File file = new File(filePath);
180         String fileName = file.getName();
181         String[] temps = fileName.split("\\.");
182         if (temps.length < SPLIT_LENGTH) {
183             return "";
184         }
185         return temps[temps.length - 1];
186     }
187 
188     /**
189      * Write data in file to output stream
190      *
191      * @param file input file path.
192      * @param dos output stream.
193      * @return true, if write successfully.
194      */
writeFileToDos(String file, DataOutputStream dos)195     public static boolean writeFileToDos(String file, DataOutputStream dos) {
196         if (dos == null) {
197             return false;
198         }
199         File src = new File(file);
200         try (FileInputStream fileStream = new FileInputStream(src)) {
201             int temp;
202             byte[] buf = new byte[FILE_BUFFER_BLOCK];
203             while ((temp = fileStream.read(buf)) > 0) {
204                 dos.write(buf, 0, temp);
205             }
206             return true;
207         } catch (FileNotFoundException e) {
208             LOGGER.error("Failed to get input stream object.");
209         } catch (IOException e) {
210             LOGGER.error("Failed to read or write data.");
211         }
212         return false;
213     }
214 
215     /**
216      * Write byte array to output stream
217      *
218      * @param data byte array
219      * @param dos output stream
220      * @return true, if write successfully.
221      */
writeByteToDos(byte[] data, DataOutputStream dos)222     public static boolean writeByteToDos(byte[] data, DataOutputStream dos) {
223         try {
224             dos.write(data);
225         } catch (IOException e) {
226             LOGGER.error("Faile to write data to output stream.");
227             return false;
228         }
229         return true;
230     }
231 
232     /**
233      * Get length of file.
234      *
235      * @param filePath input file path.
236      * @return long value of file length.
237      */
getFileLen(String filePath)238     public static long getFileLen(String filePath) {
239         File file = new File(filePath);
240         if (file.exists() && file.isFile()) {
241             return file.length();
242         }
243         return -1;
244     }
245 
246     /**
247      * Write byte array data to output file.
248      *
249      * @param signHeadByte byte array data.
250      * @param outFile output file path.
251      * @return true, if write successfully.
252      */
writeByteToOutFile(byte[] signHeadByte, String outFile)253     public static boolean writeByteToOutFile(byte[] signHeadByte, String outFile) {
254         try (OutputStream ops = new FileOutputStream(outFile, true)) {
255             ops.write(signHeadByte, 0, signHeadByte.length);
256             ops.flush();
257             return true;
258         } catch (FileNotFoundException e) {
259             LOGGER.error("Failed to get output stream object, outfile: " + outFile);
260         } catch (IOException e) {
261             LOGGER.error("Failed to write data to ops, outfile: " + outFile);
262         }
263         return false;
264     }
265 
266     /**
267      * Check input file is valid.
268      *
269      * @param file input file.
270      * @throws IOException file is a directory or can't be read.
271      */
isValidFile(File file)272     public static void isValidFile(File file) throws IOException {
273         if (!file.exists()) {
274             throw new FileNotFoundException("File '" + file + "' does not exist");
275         }
276 
277         if (file.isDirectory()) {
278             throw new IOException("File '" + file + "' exists but is a directory");
279         }
280 
281         if (!file.canRead()) {
282             throw new IOException("File '" + file + "' cannot be read");
283         }
284     }
285 
286     /**
287      * Open an input stream of input file safely.
288      * @param file input file.
289      * @return an input stream of input file
290      * @throws IOException file is a directory or can't be read.
291      */
openInputStream(File file)292     public static FileInputStream openInputStream(File file) throws IOException {
293         isValidFile(file);
294         return new FileInputStream(file);
295     }
296 
toByteArray(final InputStream input, final int size)297     private static byte[] toByteArray(final InputStream input, final int size) throws IOException {
298         if (size < 0) {
299             throw new IllegalArgumentException("Size must be equal or greater than zero: " + size);
300         }
301 
302         if (size == 0) {
303             return EMPTY_BYTE_ARRAY;
304         }
305 
306         final byte[] data = new byte[size];
307         int offset = 0;
308         int read;
309 
310         while (offset < size && (read = input.read(data, offset, size - offset)) != FILE_END) {
311             offset += read;
312         }
313 
314         if (offset != size) {
315             throw new IOException("Unexpected read size. current: " + offset + ", expected: " + size);
316         }
317 
318         return data;
319     }
320 
321     /**
322      * Read file to byte array.
323      *
324      * @param file input file.
325      * @return byte array of file-content.
326      * @throws IOException fill exception
327      */
readFileToByteArray(File file)328     public static byte[] readFileToByteArray(File file) throws IOException {
329         try (InputStream in = openInputStream(file)) {
330             final long fileLength = file.length();
331             if (fileLength > Integer.MAX_VALUE) {
332                 throw new IllegalArgumentException("Size cannot be greater than Integer max value: " + fileLength);
333             }
334             return toByteArray(in, (int) fileLength);
335         }
336     }
337 
338     /**
339      * Write a string to file
340      *
341      * @param source String will be written.
342      * @param filePath path to write file.
343      * @param charset a charset
344      * @throws IOException write error.
345      */
writeStringToFile(String source, String filePath, Charset charset)346     public static void writeStringToFile(String source, String filePath, Charset charset) throws IOException {
347         try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
348                 new FileOutputStream(filePath), charset))) {
349             writer.write(source);
350             writer.flush();
351         }
352     }
353 }
354