• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 ohos;
17 
18 import java.io.BufferedInputStream;
19 import java.io.BufferedOutputStream;
20 import java.io.BufferedReader;
21 import java.io.Closeable;
22 import java.io.File;
23 import java.io.FileInputStream;
24 import java.io.FileOutputStream;
25 import java.io.FileNotFoundException;
26 import java.io.InputStream;
27 import java.io.InputStreamReader;
28 import java.io.IOException;
29 import java.io.OutputStream;
30 import java.security.NoSuchAlgorithmException;
31 import java.util.ArrayList;
32 import java.util.Enumeration;
33 import java.util.HashMap;
34 import java.util.Optional;
35 import java.util.regex.Pattern;
36 import java.util.zip.ZipEntry;
37 import java.util.zip.ZipFile;
38 import java.util.zip.ZipInputStream;
39 import java.security.MessageDigest;
40 
41 /**
42  * file tools
43  *
44  */
45 class FileUtils {
46     private static final int BUFFER_SIZE = 1024;
47     private static final int SHA256_BUFFER_SIZE = 10240;
48     private static final Log LOG = new Log(FileUtils.class.toString());
49     private static final String RESOURCE_PATH = "resources/base/profile/";
50     private static final String SHA256 = "SHA-256";
51     private static final String PATTERN = "[0-9A-Za-z/].{0,255}";
52 
53     /**
54      * generate fileData byte stream
55      *
56      * @param filePath file path
57      * @return byte array
58      */
getFileData(final String filePath)59     public static byte[] getFileData(final String filePath) {
60         File file = new File(filePath);
61         long fileSize = file.length();
62         byte[] buffer = new byte[(int) fileSize];
63         if (fileSize > Integer.MAX_VALUE) {
64             LOG.error("file too big.");
65             return buffer;
66         }
67         FileInputStream fi = null;
68         try {
69             fi = new FileInputStream(file);
70             int offset = 0;
71             int numRead = 0;
72             while (offset < buffer.length && (numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0) {
73                 offset += numRead;
74             }
75         } catch (IOException exception) {
76             LOG.error("getFileData IOException error: " + exception.getMessage());
77             return new byte[(int) fileSize];
78         } finally {
79             closeStream(fi);
80         }
81         return buffer;
82     }
83 
84     /**
85      * search filePath for special fileName
86      *
87      * @param fileName file name
88      * @param directory dir path
89      * @return filePath
90      */
searchFile(final String fileName, final String directory)91     public static Optional<String> searchFile(final String fileName, final String directory) {
92         ArrayList<String> fileList = new ArrayList<>();
93         getFileList(directory, fileList);
94         for (String fileItem : fileList) {
95             if (fileItem.endsWith(fileName)) {
96                 return Optional.ofNullable(fileItem);
97             }
98         }
99         return Optional.empty();
100     }
101 
102     /**
103      * get file list in filePath
104      *
105      * @param filePath file path
106      * @param fileList file path in arrayList
107      */
getFileList(final String filePath, ArrayList<String> fileList)108     public static void getFileList(final String filePath, ArrayList<String> fileList) {
109         File file = new File(filePath);
110         if (!file.exists()) {
111             LOG.error("getFileList: file is not exists.");
112             return;
113         }
114         File[] files = file.listFiles();
115         if (files == null) {
116             LOG.error("getFileList: no file in this file path.");
117             return;
118         }
119         for (File f : files) {
120             try {
121                 if (f.isFile()) {
122                     fileList.add(f.getCanonicalPath());
123                 } else if (f.isDirectory()) {
124                     getFileList(f.getCanonicalPath(), fileList);
125                 } else {
126                     LOG.error("It's not file or directory.");
127                 }
128             } catch (IOException msg) {
129                 LOG.error("IOException error: " + msg.getMessage());
130                 return;
131             }
132         }
133     }
134 
135     /**
136      * get string from file
137      *
138      * @param filePath file path
139      * @return String for file
140      */
getFileContent(final String filePath)141     public static Optional<String> getFileContent(final String filePath) {
142         if (filePath.isEmpty()) {
143             return Optional.empty();
144         }
145         BufferedReader reader = null;
146         FileInputStream fileInputStream = null;
147         InputStreamReader inputStreamReader = null;
148         StringBuilder content = new StringBuilder();
149         try {
150             fileInputStream = new FileInputStream(filePath);
151             inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
152             reader = new BufferedReader(inputStreamReader);
153             String tempString;
154             while ((tempString = reader.readLine()) != null) {
155                 content.append(tempString);
156             }
157         } catch (IOException msg) {
158             LOG.error("get file content fail, msg is " + msg.getMessage());
159             return Optional.empty();
160         } finally {
161             closeStream(reader);
162             closeStream(inputStreamReader);
163             closeStream(fileInputStream);
164         }
165         return Optional.ofNullable(content.toString());
166     }
167 
168     /**
169      * close file stream
170      *
171      * @param fileStream file stream
172      */
closeStream(Closeable fileStream)173     public static void closeStream(Closeable fileStream) {
174         try {
175             if (fileStream != null) {
176                 fileStream.close();
177             }
178         } catch (IOException msg) {
179             LOG.error("stream close Error, msg is " + msg.getMessage());
180         }
181     }
182 
183     /**
184      * delete file
185      *
186      * @param path file path which will be deleted
187      */
deleteFile(final String path)188     public static void deleteFile(final String path) {
189         File file = new File(path);
190         if (file.exists()) {
191             file.delete();
192         }
193     }
194 
195     /**
196      * unzip hap package to path
197      *
198      * @param hapPath zip file
199      * @param destDir path after unzip file
200      */
unzip(final String hapPath, final String destDir)201     public static void unzip(final String hapPath, final String destDir) {
202         File file = new File(destDir);
203         if (!file.exists()) {
204             file.mkdirs();
205         }
206 
207         ZipFile zipFile = null;
208         BufferedInputStream bis = null;
209         BufferedOutputStream bos = null;
210         FileOutputStream fos = null;
211         try {
212             zipFile = new ZipFile(hapPath);
213             Enumeration<? extends ZipEntry> entries = zipFile.entries();
214             int entriesNum = 0;
215             while (entries.hasMoreElements()) {
216                 entriesNum++;
217                 ZipEntry entry = entries.nextElement();
218                 if (entry == null) {
219                     continue;
220                 }
221                 String filePath = destDir + File.separator + entry.getName();
222                 if (!matchPattern(filePath)) {
223                     throw new BundleException("Input invalid file " + filePath);
224                 }
225                 if (entry.isDirectory()) {
226                     new File(filePath).mkdirs();
227                     continue;
228                 }
229 
230                 bis = new BufferedInputStream(zipFile.getInputStream(entry));
231                 File newFile = new File(filePath);
232                 File parent = newFile.getParentFile();
233                 if (parent != null && (!parent.exists())) {
234                     parent.mkdirs();
235                 }
236 
237                 fos = new FileOutputStream(newFile);
238                 bos = new BufferedOutputStream(fos, BUFFER_SIZE);
239 
240                 int count;
241                 int total = 0;
242                 byte[] data = new byte[BUFFER_SIZE];
243                 while ((count = bis.read(data, 0, BUFFER_SIZE)) != -1) {
244                     bos.write(data, 0, count);
245                     total += count;
246                 }
247 
248                 bos.flush();
249                 bos.close();
250                 fos.close();
251                 bis.close();
252             }
253         } catch (IOException | BundleException exception) {
254             LOG.error("unzip file failed " + exception.getMessage());
255         } finally {
256             closeStream(bos);
257             closeStream(fos);
258             closeStream(bis);
259             closeStream(zipFile);
260         }
261     }
262 
263     /**
264      * delete directory
265      *
266      * @param directory dir path which will be deleted
267      */
deleteDirectory(final String directory)268     public static void deleteDirectory(final String directory) {
269         File dir = new File(directory);
270         if (!dir.exists()) {
271             return;
272         }
273 
274         File[] fileList = dir.listFiles();
275         if (fileList == null) {
276             return;
277         }
278         for (File file : fileList) {
279             try {
280                 if (file.isFile()) {
281                     file.delete();
282                 } else if (file.isDirectory()) {
283                     deleteDirectory(file.getCanonicalPath());
284                 } else {
285                     LOG.error("It's not file or directory.");
286                 }
287             } catch (IOException msg) {
288                 LOG.error("deleteDirectory IOException : " + msg.getMessage());
289             }
290         }
291         dir.delete();
292     }
293 
294     /**
295      * format filepath
296      *
297      * @param filePath file path which is need to format
298      * @return canonicalPath for filePath
299      */
getFormatedPath(final String filePath)300     public static Optional<String> getFormatedPath(final String filePath) {
301         String absPath;
302         try {
303             File file = new File(filePath);
304             absPath = file.getCanonicalPath();
305         } catch (IOException msg) {
306             LOG.error("format path IOException : " + msg.getMessage());
307             return Optional.empty();
308         }
309         return Optional.of(absPath);
310     }
311 
312     /**
313      * check file whether is exist or not
314      *
315      * @param filePath bin file path
316      * @return true: file is exist, false: file is not exist
317      */
checkFileIsExists(final String filePath)318     public static boolean checkFileIsExists(final String filePath) {
319         if (filePath.isEmpty()) {
320             return false;
321         }
322 
323         Optional<String> absFilePath = getFormatedPath(filePath);
324         if (!absFilePath.isPresent()) {
325             return false;
326         }
327 
328         File file = new File(absFilePath.get());
329         if (!file.exists()) {
330             return false;
331         }
332         return true;
333     }
334 
335     /**
336      * copy a file to another place.
337      *
338      * @param sourceFile is the source file
339      * @param destFile is the destination file
340      * @throws IOException FileNotFoundException|IOException.
341      */
copyFile(File sourceFile, File destFile)342     public static void copyFile(File sourceFile, File destFile) throws IOException, BundleException {
343         if (sourceFile == null || destFile == null) {
344             String errMsg = "CompressorFileUtil::copyFile input file is null.";
345             LOG.error(errMsg);
346             throw new BundleException(errMsg);
347         }
348         InputStream inputStream = null;
349         OutputStream outputStream = null;
350         try {
351             inputStream = new FileInputStream(sourceFile);
352             outputStream = new FileOutputStream(destFile);
353             byte[] buffer = new byte[BUFFER_SIZE];
354             int length;
355             while ((length = inputStream.read(buffer)) > 0) {
356                 outputStream.write(buffer, 0, length);
357             }
358         } finally {
359             Utility.closeStream(inputStream);
360             Utility.closeStream(outputStream);
361         }
362     }
363 
364     /**
365      * make a directory if not exist.
366      *
367      * @param dirFile is the directory file
368      * @throws IOException FileNotFoundException|IOException.
369      */
makeDir(File dirFile)370     public static void makeDir(File dirFile) throws IOException, BundleException {
371         if (dirFile == null) {
372             String errMsg = "CompressorFileUtil::makeDir input file is null.";
373             LOG.error(errMsg);
374             throw new BundleException(errMsg);
375         }
376         dirFile.mkdirs();
377     }
378 
379     /**
380      * check json type code in haps.
381      *
382      * @param srcFile source file to zip
383      * @return true is for successful and false is for failed
384      * @throws BundleException FileNotFoundException|IOException.
385      */
getJsonInZips(File srcFile, String jsonName)386     public static String getJsonInZips(File srcFile, String jsonName) throws BundleException {
387         String fileStr = srcFile.getPath();
388         ZipFile zipFile = null;
389         FileInputStream zipInput = null;
390         ZipInputStream zin = null;
391         InputStream inputStream = null;
392         InputStreamReader reader = null;
393         BufferedReader br = null;
394         ZipEntry entry = null;
395         StringBuilder jsonStr = new StringBuilder();
396         try {
397             zipFile = new ZipFile(srcFile);
398             zipInput = new FileInputStream(fileStr);
399             zin = new ZipInputStream(zipInput);
400             while ((entry = zin.getNextEntry()) != null) {
401                 if (entry.getName().toLowerCase().equals(jsonName)) {
402                     inputStream = zipFile.getInputStream(entry);
403                     reader = new InputStreamReader(inputStream);
404                     br = new BufferedReader(reader);
405                     String line;
406                     while ((line = br.readLine()) != null) {
407                         jsonStr.append(line);
408                     }
409                     inputStream.close();
410                 }
411             }
412             jsonStr = new StringBuilder(jsonStr.toString().replaceAll("\r|\n|\t", ""));
413         } catch (IOException exception) {
414             LOG.error("Compressor::checkModuleTypeInHaps io exception: " + exception.getMessage());
415             throw new BundleException("Compressor::checkModuleTypeInHaps failed.");
416         } finally {
417             Utility.closeStream(zipFile);
418             Utility.closeStream(zipInput);
419             Utility.closeStream(zin);
420             Utility.closeStream(inputStream);
421             Utility.closeStream(reader);
422             Utility.closeStream(br);
423         }
424         return jsonStr.toString();
425     }
426 
427     /**
428      * get all resource file in profile.
429      *
430      * @param zipFile is the hap file
431      * @throws BundleException when get profile json file failed
432      */
getProfileJson(ZipFile zipFile)433     static HashMap<String, String> getProfileJson(ZipFile zipFile) throws BundleException {
434         HashMap<String, String> resourceMap = new HashMap<>();
435         try {
436             final Enumeration<? extends ZipEntry> entries = zipFile.entries();
437             while (entries.hasMoreElements()) {
438                 final ZipEntry entry = entries.nextElement();
439                 if (entry.getName().contains(RESOURCE_PATH)) {
440                     String filePath = entry.getName();
441                     String fileName = filePath.replaceAll(RESOURCE_PATH, "");
442                     String fileContent = getFileStringFromZip(filePath, zipFile);
443                     resourceMap.put(fileName, fileContent);
444                 }
445             }
446         } catch (IOException e) {
447             LOG.error("FileUtil::getProfileJson IOException.");
448             throw new BundleException("FileUtil::getProfileJson failed.");
449         }
450         return resourceMap;
451     }
452 
453     /**
454      * get file content in string from zip
455      *
456      * @param fileName is the file name we want to read
457      * @param zipFile is the zip file
458      */
getFileStringFromZip(String fileName, ZipFile zipFile)459     public static String getFileStringFromZip(String fileName, ZipFile zipFile)
460             throws IOException {
461         ZipEntry entry = zipFile.getEntry(fileName);
462         if (entry == null) {
463             LOG.debug("Uncompress::readStringFromFile " + fileName + " not found exception.");
464             return "";
465         }
466         InputStream fileInputStream = null;
467         BufferedReader bufferedReader = null;
468         try {
469             fileInputStream = zipFile.getInputStream(entry);
470             bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
471             String line;
472             StringBuilder sb = new StringBuilder();
473             while ((line = bufferedReader.readLine()) != null) {
474                 sb.append(line);
475             }
476             return sb.toString();
477         } finally {
478             Utility.closeStream(bufferedReader);
479             Utility.closeStream(fileInputStream);
480         }
481     }
482 
483     /**
484      * get sha-256 for file
485      *
486      * @param hapPath is the input path of file
487      */
getSha256(String hapPath)488     public static String getSha256(String hapPath) {
489         String sha256 = "";
490         BufferedInputStream inputStream = null;
491         try {
492             File file = new File(hapPath);
493             inputStream = new BufferedInputStream(new FileInputStream(file));
494             byte[] buffer = new byte[SHA256_BUFFER_SIZE];
495             MessageDigest md5 = MessageDigest.getInstance(SHA256);
496             int size = -1;
497             while ((size = inputStream.read(buffer)) != -1) {
498                 md5.update(buffer, 0, size);
499             }
500             sha256 = toHex(md5.digest());
501         } catch (FileNotFoundException e) {
502             LOG.error("input hap file is not found.");
503         } catch (NoSuchAlgorithmException e) {
504             LOG.error("can not provide sha-256 algorithm.");
505         } catch (IOException e) {
506             LOG.error("input hap IO exception.");
507         } finally {
508             Utility.closeStream(inputStream);
509         }
510         return sha256;
511     }
512 
toHex(byte[] data)513     private static String toHex(byte[] data) {
514         StringBuilder hexString = new StringBuilder();
515         for (byte item : data) {
516             hexString.append(Integer.toHexString(item & 0xFF));
517         }
518         return hexString.toString();
519     }
520 
521     /**
522      * unzip file
523      *
524      * @param zipFilePath is the zipFilePath
525      * @param destDirPath is the output dest path
526      */
unzipFile(String zipFilePath, String destDirPath)527     public static boolean unzipFile(String zipFilePath, String destDirPath) {
528         boolean success = false;
529         File destDir = new File(destDirPath);
530         if (!destDir.exists()) {
531             destDir.mkdirs();
532         }
533         ZipInputStream zipInputStream = null;
534         try {
535             zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath));
536             ZipEntry entry = zipInputStream.getNextEntry();
537             while (entry != null) {
538                 String filePath = destDirPath + File.separator + entry.getName();
539                 if (!matchPattern(filePath)) {
540                     LOG.error("Input invalid file " + filePath + ".");
541                     return false;
542                 }
543                 if (!entry.isDirectory()) {
544                     extractFile(zipInputStream, filePath);
545                 } else {
546                     File dir = new File(filePath);
547                     dir.mkdirs();
548                 }
549                 zipInputStream.closeEntry();
550                 entry = zipInputStream.getNextEntry();
551             }
552             success = true;
553         } catch (IOException e) {
554             LOG.error("FileUtil::unzipFile failed, IOException is " + e.getMessage());
555         } finally {
556             Utility.closeStream(zipInputStream);
557         }
558         return success;
559     }
560 
extractFile(ZipInputStream zipInputStream, String filePath)561     private static void extractFile(ZipInputStream zipInputStream, String filePath) {
562         BufferedOutputStream bufferedOutputStream = null;
563         try {
564             if (!matchPattern(filePath)) {
565                 throw new BundleException("input invalid file " + filePath + ".");
566             }
567             bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filePath));
568             byte[] bytes = new byte[BUFFER_SIZE];
569             int readLength = 0;
570             while ((readLength = zipInputStream.read(bytes)) != -1) {
571                 bufferedOutputStream.write(bytes, 0, readLength);
572             }
573         } catch (IOException | BundleException e) {
574             LOG.error("FileUtil::extractFile failed, Exception is " + e.getMessage());
575         } finally {
576             Utility.closeStream(bufferedOutputStream);
577         }
578     }
579 
matchPattern(String path)580     static boolean matchPattern(String path) {
581         if (!Pattern.matches(PATTERN, path)) {
582             LOG.error("input invalid file of " + path + ".");
583             return false;
584         }
585         return true;
586     }
587 
588     /**
589      * getFileSize
590      *
591      * @param filePath is the input file path
592      * @return file length
593      */
getFileSize(String filePath)594     public static long getFileSize(String filePath) {
595         File file = new File(filePath);
596         if (file.exists() && file.isFile()) {
597             return file.length();
598         }
599         LOG.error("input " + filePath + " is not a valid file.");
600         return 0;
601     }
602 }
603