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