clean code
This commit is contained in:
parent
55d89af412
commit
f5cb3490fd
|
|
@ -1,5 +1,7 @@
|
||||||
package com.storm.wind.xpatch;
|
package com.storm.wind.xpatch;
|
||||||
|
|
||||||
|
import static org.apache.commons.io.FileUtils.copyFile;
|
||||||
|
|
||||||
import com.storm.wind.xpatch.base.BaseCommand;
|
import com.storm.wind.xpatch.base.BaseCommand;
|
||||||
import com.storm.wind.xpatch.task.ApkModifyTask;
|
import com.storm.wind.xpatch.task.ApkModifyTask;
|
||||||
import com.storm.wind.xpatch.task.BuildAndSignApkTask;
|
import com.storm.wind.xpatch.task.BuildAndSignApkTask;
|
||||||
|
|
@ -21,8 +23,6 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static org.apache.commons.io.FileUtils.copyFile;
|
|
||||||
|
|
||||||
public class MainCommand extends BaseCommand {
|
public class MainCommand extends BaseCommand {
|
||||||
|
|
||||||
private String apkPath;
|
private String apkPath;
|
||||||
|
|
@ -31,7 +31,7 @@ public class MainCommand extends BaseCommand {
|
||||||
|
|
||||||
@Opt(opt = "o", longOpt = "output", description = "output .apk file, default is " +
|
@Opt(opt = "o", longOpt = "output", description = "output .apk file, default is " +
|
||||||
"$source_apk_dir/[file-name]-xposed-signed.apk", argName = "out-apk-file")
|
"$source_apk_dir/[file-name]-xposed-signed.apk", argName = "out-apk-file")
|
||||||
private String output; // 输出的apk文件的目录以及名称
|
private String output;
|
||||||
|
|
||||||
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
|
@Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite")
|
||||||
private boolean forceOverwrite = false;
|
private boolean forceOverwrite = false;
|
||||||
|
|
@ -43,7 +43,6 @@ public class MainCommand extends BaseCommand {
|
||||||
description = "disable craching the apk's signature.")
|
description = "disable craching the apk's signature.")
|
||||||
private boolean disableCrackSignature = false;
|
private boolean disableCrackSignature = false;
|
||||||
|
|
||||||
// 使用dex文件中插入代码的方式修改apk,而不是默认的修改Manifest中Application name的方式
|
|
||||||
@Opt(opt = "dex", longOpt = "dex", hasArg = false, description = "insert code into the dex file, not modify manifest application name attribute")
|
@Opt(opt = "dex", longOpt = "dex", hasArg = false, description = "insert code into the dex file, not modify manifest application name attribute")
|
||||||
private boolean dexModificationMode = false;
|
private boolean dexModificationMode = false;
|
||||||
|
|
||||||
|
|
@ -62,7 +61,6 @@ public class MainCommand extends BaseCommand {
|
||||||
argName = "new-version-name")
|
argName = "new-version-name")
|
||||||
private String versionName;
|
private String versionName;
|
||||||
|
|
||||||
// 原来apk中dex文件的数量
|
|
||||||
private int dexFileCount = 0;
|
private int dexFileCount = 0;
|
||||||
|
|
||||||
private static final String UNZIP_APK_FILE_NAME = "apk-unzip-files";
|
private static final String UNZIP_APK_FILE_NAME = "apk-unzip-files";
|
||||||
|
|
@ -73,7 +71,7 @@ public class MainCommand extends BaseCommand {
|
||||||
new MainCommand().doMain(args);
|
new MainCommand().doMain(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fuckIfFail(boolean b) {
|
static public void fuckIfFail(boolean b) {
|
||||||
if (!b) {
|
if (!b) {
|
||||||
throw new IllegalStateException("wtf", new Throwable("DUMPBT"));
|
throw new IllegalStateException("wtf", new Throwable("DUMPBT"));
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +175,8 @@ public class MainCommand extends BaseCommand {
|
||||||
// new manifest may not exist
|
// new manifest may not exist
|
||||||
if (manifestFile.exists() && manifestFile.length() > 0) {
|
if (manifestFile.exists() && manifestFile.length() > 0) {
|
||||||
fuckIfFail(manifestFileNew.delete());
|
fuckIfFail(manifestFileNew.delete());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
fuckIfFail(manifestFileNew.renameTo(manifestFile));
|
fuckIfFail(manifestFileNew.renameTo(manifestFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.storm.wind.xpatch.task;
|
package com.storm.wind.xpatch.task;
|
||||||
|
|
||||||
import com.android.apksigner.ApkSignerTool;
|
import com.android.apksigner.ApkSignerTool;
|
||||||
|
import com.storm.wind.xpatch.MainCommand;
|
||||||
import com.storm.wind.xpatch.util.FileUtils;
|
import com.storm.wind.xpatch.util.FileUtils;
|
||||||
import com.storm.wind.xpatch.util.ShellCmdUtil;
|
import com.storm.wind.xpatch.util.ShellCmdUtil;
|
||||||
|
|
||||||
|
|
@ -27,40 +28,44 @@ public class BuildAndSignApkTask implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
File unzipApkFile = new File(unzipApkFilePath);
|
try {
|
||||||
|
File unzipApkFile = new File(unzipApkFilePath);
|
||||||
|
|
||||||
// 将文件压缩到当前apk文件的上一级目录上
|
String unsignedApkPath = unzipApkFile.getParent() + File.separator + "unsigned.apk";
|
||||||
String unsignedApkPath = unzipApkFile.getParent() + File.separator + "unsigned.apk";
|
FileUtils.compressToZip(unzipApkFilePath, unsignedApkPath);
|
||||||
FileUtils.compressToZip(unzipApkFilePath, unsignedApkPath);
|
|
||||||
|
|
||||||
// 将签名文件复制从assets目录下复制出来
|
String keyStoreFilePath = unzipApkFile.getParent() + File.separator + "keystore";
|
||||||
String keyStoreFilePath = unzipApkFile.getParent() + File.separator + "keystore";
|
|
||||||
|
|
||||||
File keyStoreFile = new File(keyStoreFilePath);
|
File keyStoreFile = new File(keyStoreFilePath);
|
||||||
// assets/keystore分隔符不能使用File.separator,否则在windows上抛出IOException !!!
|
// assets/keystore分隔符不能使用File.separator,否则在windows上抛出IOException !!!
|
||||||
String keyStoreAssetPath;
|
String keyStoreAssetPath;
|
||||||
if (isAndroid()) {
|
if (isAndroid()) {
|
||||||
// BKS-V1 类型
|
// BKS-V1 类型
|
||||||
keyStoreAssetPath = "assets/android.keystore";
|
keyStoreAssetPath = "assets/android.keystore";
|
||||||
} else {
|
}
|
||||||
// BKS 类型
|
else {
|
||||||
keyStoreAssetPath = "assets/keystore";
|
// BKS 类型
|
||||||
|
keyStoreAssetPath = "assets/keystore";
|
||||||
|
}
|
||||||
|
|
||||||
|
FileUtils.copyFileFromJar(keyStoreAssetPath, keyStoreFilePath);
|
||||||
|
|
||||||
|
boolean signResult = signApk(unsignedApkPath, keyStoreFilePath, signedApkPath);
|
||||||
|
|
||||||
|
File unsignedApkFile = new File(unsignedApkPath);
|
||||||
|
File signedApkFile = new File(signedApkPath);
|
||||||
|
// delete unsigned apk file
|
||||||
|
if (!keepUnsignedApkFile && unsignedApkFile.exists() && signedApkFile.exists() && signResult) {
|
||||||
|
MainCommand.fuckIfFail(unsignedApkFile.delete());
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the keystore file
|
||||||
|
if (keyStoreFile.exists()) {
|
||||||
|
MainCommand.fuckIfFail(keyStoreFile.delete());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception err) {
|
||||||
FileUtils.copyFileFromJar(keyStoreAssetPath, keyStoreFilePath);
|
throw new IllegalStateException("wtf", err);
|
||||||
|
|
||||||
boolean signResult = signApk(unsignedApkPath, keyStoreFilePath, signedApkPath);
|
|
||||||
|
|
||||||
File unsignedApkFile = new File(unsignedApkPath);
|
|
||||||
File signedApkFile = new File(signedApkPath);
|
|
||||||
// delete unsigned apk file
|
|
||||||
if (!keepUnsignedApkFile && unsignedApkFile.exists() && signedApkFile.exists() && signResult) {
|
|
||||||
unsignedApkFile.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete the keystore file
|
|
||||||
if (keyStoreFile.exists()) {
|
|
||||||
keyStoreFile.delete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +92,7 @@ public class BuildAndSignApkTask implements Runnable {
|
||||||
.append(" " + apkPath + " ")
|
.append(" " + apkPath + " ")
|
||||||
.append(" -digestalg SHA1 -sigalg SHA1withRSA ")
|
.append(" -digestalg SHA1 -sigalg SHA1withRSA ")
|
||||||
.append(" key0 ");
|
.append(" key0 ");
|
||||||
// System.out.println("\n" + signCmd + "\n");
|
System.out.println("\n" + signCmd + "\n");
|
||||||
String result = ShellCmdUtil.execCmd(signCmd.toString(), null);
|
String result = ShellCmdUtil.execCmd(signCmd.toString(), null);
|
||||||
System.out.println(" sign apk time is :" + ((System.currentTimeMillis() - time) / 1000) +
|
System.out.println(" sign apk time is :" + ((System.currentTimeMillis() - time) / 1000) +
|
||||||
"s\n\n" + " result=" + result);
|
"s\n\n" + " result=" + result);
|
||||||
|
|
@ -96,7 +101,8 @@ public class BuildAndSignApkTask implements Runnable {
|
||||||
System.out.println(" keystore not exist :" + keystoreFile.getAbsolutePath() +
|
System.out.println(" keystore not exist :" + keystoreFile.getAbsolutePath() +
|
||||||
" please sign the apk by hand. \n");
|
" please sign the apk by hand. \n");
|
||||||
return false;
|
return false;
|
||||||
} catch (Throwable e) {
|
}
|
||||||
|
catch (Throwable e) {
|
||||||
System.out.println("use default jarsigner to sign apk failed, fail msg is :" +
|
System.out.println("use default jarsigner to sign apk failed, fail msg is :" +
|
||||||
e.toString());
|
e.toString());
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -107,7 +113,8 @@ public class BuildAndSignApkTask implements Runnable {
|
||||||
boolean isAndroid = true;
|
boolean isAndroid = true;
|
||||||
try {
|
try {
|
||||||
Class.forName("android.content.Context");
|
Class.forName("android.content.Context");
|
||||||
} catch (ClassNotFoundException e) {
|
}
|
||||||
|
catch (ClassNotFoundException e) {
|
||||||
isAndroid = false;
|
isAndroid = false;
|
||||||
}
|
}
|
||||||
return isAndroid;
|
return isAndroid;
|
||||||
|
|
@ -142,7 +149,8 @@ public class BuildAndSignApkTask implements Runnable {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ApkSignerTool.main(commandArray);
|
ApkSignerTool.main(commandArray);
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
package com.storm.wind.xpatch.task;
|
package com.storm.wind.xpatch.task;
|
||||||
|
|
||||||
import com.storm.wind.xpatch.util.ApkSignatureHelper;
|
import com.storm.wind.xpatch.util.ApkSignatureHelper;
|
||||||
import com.storm.wind.xpatch.util.FileUtils;
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Wind
|
* Created by Wind
|
||||||
|
|
@ -25,19 +27,19 @@ public class SaveApkSignatureTask implements Runnable {
|
||||||
// First, get the original signature
|
// First, get the original signature
|
||||||
String originalSignature = ApkSignatureHelper.getApkSignInfo(apkPath);
|
String originalSignature = ApkSignatureHelper.getApkSignInfo(apkPath);
|
||||||
if (originalSignature == null || originalSignature.isEmpty()) {
|
if (originalSignature == null || originalSignature.isEmpty()) {
|
||||||
System.out.println(" Get original signature failed !!!!");
|
System.out.println("Get original signature failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then, save the signature chars to the asset file
|
// Then, save the signature chars to the asset file
|
||||||
File file = new File(dstFilePath);
|
File file = new File(dstFilePath);
|
||||||
File fileParent = file.getParentFile();
|
try {
|
||||||
if (!fileParent.exists()) {
|
FileUtils.write(file, originalSignature, StandardCharsets.UTF_8);
|
||||||
if(!fileParent.mkdirs()){
|
}
|
||||||
System.out.println("mkdir fails " + fileParent.getAbsolutePath());
|
catch (Exception err) {
|
||||||
}
|
// just crash now
|
||||||
|
// todo: pass result to caller
|
||||||
|
throw new IllegalStateException("wtf", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileUtils.writeFile(dstFilePath, originalSignature);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.storm.wind.xpatch.task;
|
package com.storm.wind.xpatch.task;
|
||||||
|
|
||||||
import com.storm.wind.xpatch.util.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
|
@ -24,19 +24,26 @@ public class SaveOriginalApplicationNameTask implements Runnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ensureDstFileCreated();
|
try {
|
||||||
FileUtils.writeFile(dstFilePath, applcationName);
|
ensureDstFileCreated();
|
||||||
|
FileUtils.write(new File(dstFilePath), applcationName);
|
||||||
|
}
|
||||||
|
catch (Exception err) {
|
||||||
|
// just crash
|
||||||
|
// todo: pass result to caller
|
||||||
|
throw new IllegalStateException("wtf", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureDstFileCreated() {
|
private void ensureDstFileCreated() {
|
||||||
File dstParentFile = new File(dstFilePath);
|
File dstParentFile = new File(dstFilePath);
|
||||||
if (!dstParentFile.getParentFile().getParentFile().exists()) {
|
if (!dstParentFile.getParentFile().getParentFile().exists()) {
|
||||||
if(!dstParentFile.getParentFile().getParentFile().mkdirs()){
|
if (!dstParentFile.getParentFile().getParentFile().mkdirs()) {
|
||||||
throw new IllegalStateException("mkdir fail");
|
throw new IllegalStateException("mkdir fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dstParentFile.getParentFile().exists()) {
|
if (!dstParentFile.getParentFile().exists()) {
|
||||||
if(!dstParentFile.getParentFile().mkdirs()){
|
if (!dstParentFile.getParentFile().mkdirs()) {
|
||||||
throw new IllegalStateException("mkdir fail");
|
throw new IllegalStateException("mkdir fail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,14 @@
|
||||||
package com.storm.wind.xpatch.util;
|
package com.storm.wind.xpatch.util;
|
||||||
|
|
||||||
import org.apache.commons.io.FileSystemUtils;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.BufferedWriter;
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.channels.FileChannel;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.zip.CRC32;
|
import java.util.zip.CRC32;
|
||||||
|
|
@ -79,7 +72,8 @@ public class FileUtils {
|
||||||
OutputStream out = new FileOutputStream(outPath);
|
OutputStream out = new FileOutputStream(outPath);
|
||||||
IOUtils.copy(in, out);
|
IOUtils.copy(in, out);
|
||||||
out.close();
|
out.close();
|
||||||
} catch (Exception err) {
|
}
|
||||||
|
catch (Exception err) {
|
||||||
throw new IllegalStateException("wtf", err);
|
throw new IllegalStateException("wtf", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,27 +85,10 @@ public class FileUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy an asset file into a path
|
// copy an asset file into a path
|
||||||
public static void copyFileFromJar(String inJarPath, String distPath) {
|
public static void copyFileFromJar(String inJarPath, String distPath) throws IOException {
|
||||||
|
// System.out.println("start copyFile inJarPath =" + inJarPath + " distPath = " + distPath);
|
||||||
// System.out.println("start copyFile inJarPath =" + inJarPath + " distPath = " + distPath);
|
try (InputStream inputStream = getInputStreamFromFile(inJarPath); FileOutputStream out = new FileOutputStream(distPath)) {
|
||||||
InputStream inputStream = getInputStreamFromFile(inJarPath);
|
IOUtils.copy(inputStream, out);
|
||||||
|
|
||||||
BufferedInputStream in = null;
|
|
||||||
BufferedOutputStream out = null;
|
|
||||||
try {
|
|
||||||
in = new BufferedInputStream(inputStream);
|
|
||||||
out = new BufferedOutputStream(new FileOutputStream(distPath));
|
|
||||||
|
|
||||||
int len = -1;
|
|
||||||
byte[] b = new byte[1024];
|
|
||||||
while ((len = in.read(b)) != -1) {
|
|
||||||
out.write(b, 0, len);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
close(out);
|
|
||||||
close(in);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,37 +96,26 @@ public class FileUtils {
|
||||||
File srcFile = new File(srcPath);
|
File srcFile = new File(srcPath);
|
||||||
File dstFile = new File(dstPath);
|
File dstFile = new File(dstPath);
|
||||||
if (!srcFile.exists()) {
|
if (!srcFile.exists()) {
|
||||||
System.out.println(srcPath + " does not exist !");
|
throw new IllegalStateException("wtf", new Throwable("DUMPBT"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileOutputStream out = null;
|
try (FileOutputStream out = new FileOutputStream(dstFile);
|
||||||
ZipOutputStream zipOut = null;
|
CheckedOutputStream cos = new CheckedOutputStream(out, new CRC32());
|
||||||
try {
|
ZipOutputStream zipOut = new ZipOutputStream(cos)
|
||||||
out = new FileOutputStream(dstFile);
|
) {
|
||||||
CheckedOutputStream cos = new CheckedOutputStream(out, new CRC32());
|
|
||||||
zipOut = new ZipOutputStream(cos);
|
|
||||||
String baseDir = "";
|
String baseDir = "";
|
||||||
compress(srcFile, zipOut, baseDir, true);
|
compress(srcFile, zipOut, baseDir, true);
|
||||||
} catch (IOException e) {
|
}
|
||||||
System.out.println(" compress exception = " + e.getMessage());
|
catch (IOException e) {
|
||||||
} finally {
|
throw new IllegalStateException("wtf", e);
|
||||||
try {
|
|
||||||
if (zipOut != null) {
|
|
||||||
zipOut.closeEntry();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
close(zipOut);
|
|
||||||
close(out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void compress(File file, ZipOutputStream zipOut, String baseDir, boolean isRootDir) throws IOException {
|
private static void compress(File file, ZipOutputStream zipOut, String baseDir, boolean isRootDir) throws IOException {
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
compressDirectory(file, zipOut, baseDir, isRootDir);
|
compressDirectory(file, zipOut, baseDir, isRootDir);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
compressFile(file, zipOut, baseDir);
|
compressFile(file, zipOut, baseDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -179,61 +145,14 @@ public class FileUtils {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferedInputStream bis = null;
|
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
|
||||||
try {
|
|
||||||
bis = new BufferedInputStream(new FileInputStream(file));
|
|
||||||
ZipEntry entry = new ZipEntry(baseDir + file.getName());
|
ZipEntry entry = new ZipEntry(baseDir + file.getName());
|
||||||
zipOut.putNextEntry(entry);
|
zipOut.putNextEntry(entry);
|
||||||
int count;
|
int count;
|
||||||
byte data[] = new byte[BUFFER];
|
byte[] data = new byte[BUFFER];
|
||||||
while ((count = bis.read(data, 0, BUFFER)) != -1) {
|
while ((count = bis.read(data, 0, BUFFER)) != -1) {
|
||||||
zipOut.write(data, 0, count);
|
zipOut.write(data, 0, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
|
||||||
if (null != bis) {
|
|
||||||
bis.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void writeFile(String filePath, String content) {
|
|
||||||
if (filePath == null || filePath.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (content == null || content.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File dstFile = new File(filePath);
|
|
||||||
|
|
||||||
if (!dstFile.getParentFile().exists()) {
|
|
||||||
dstFile.getParentFile().mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
FileOutputStream outputStream = null;
|
|
||||||
BufferedWriter writer = null;
|
|
||||||
try {
|
|
||||||
outputStream = new FileOutputStream(dstFile);
|
|
||||||
writer = new BufferedWriter(new OutputStreamWriter(outputStream));
|
|
||||||
writer.write(content);
|
|
||||||
writer.flush();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
close(outputStream);
|
|
||||||
close(writer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void close(Closeable closeable) {
|
|
||||||
try {
|
|
||||||
if (closeable != null) {
|
|
||||||
closeable.close();
|
|
||||||
}
|
|
||||||
} catch (IOException io) {
|
|
||||||
io.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue