/**
 * 根据inputstream生成文件
 * @param ins
 * @param file
 * @throws IOException
 */
public static void inputStreamToFile(InputStream ins, File file) throws IOException {
    OutputStream os = new FileOutputStream(file);
    int bytesRead = 0;
    byte[] buffer = new byte[0x100000];
    while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
        os.write(buffer, 0, bytesRead);
    }
    os.close();
}

 * 获取大文件(如1G)的字节数组
 *
 * @param fileName 文件路径+文件名称
 * @param isDelete 是否删除源文件
 * @return
 * @throws IOException
 */
public static byte[] readBigFileBytes(String fileName, boolean isDelete) throws IOException {
    File f = new File(fileName);
    if (!f.exists()) {
        throw new FileNotFoundException(fileName);
    }

    FileChannel channel = null;
    FileInputStream fs = null;
    try {
        fs = new FileInputStream(f);
        channel = fs.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
        while ((channel.read(byteBuffer)) > 0) {
            // do nothing
            // System.out.println("reading");
        }
        return byteBuffer.array();
    } catch (IOException e) {
        e.printStackTrace();
        throw e;
    } finally {
        try {
            channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fs.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (isDelete) {
            f.delete();
        }
    }
}

/**
 * 复制指定文件夹下的所有文件
 *
 * @param source
 * @param fil
 * @throws IOException
 */
public static void copy(File source, File fil) throws IOException {
    // 判断源目录是不是一个目录
    if (!source.isDirectory()) {
        //如果不是目录就不复制
        return;
    }
    //如果源文件存在就复制
    if (source.exists()) {
        // 获取源目录下的File对象列表
        File[] files = source.listFiles();
        for (File file2 : files) {
            //新文件夹的路径
            File file4 = null;
            if (file2.isDirectory()) {
                //新文件夹的路径
                file4 = new File(fil.getAbsolutePath());
                copy(file2, file4);
            }
            if (file2.isFile()) {
                file4 = new File(fil.getAbsolutePath() + File.separator + file2.getName());
                FileInputStream in = new FileInputStream(file2);
                FileOutputStream out = new FileOutputStream(file4);
                byte[] bs = new byte[1024 * 10240];
                int count = 0;
                //循环把源文件的内容写入新文件
                while ((count = in.read(bs, 0, bs.length)) != -1) {
                    out.write(bs, 0, count);
                }
                //关闭流
                out.flush();
                out.close();
                in.close();
            }
        }
    }
}


 * 2      * 根据byte数组,生成文件
 * 3
 */
public static void getFile(byte[] bfile, File file) {
    BufferedOutputStream bos = null;
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file);
        bos = new BufferedOutputStream(fos);
        bos.write(bfile);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
}

//根据文件生成byte数组
public static byte[] readFile2Bytes(File file, boolean isDelete) throws IOException {
    InputStream inputStream = new FileInputStream(file);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    try {
        int len = 0;
        byte[] b = new byte[10240];
        while ((len = inputStream.read(b)) != -1) {
            outputStream.write(b, 0, len);
        }
        byte[] byteArray = outputStream.toByteArray();
        return byteArray;
    } finally {
        IOUtils.close(inputStream);
        IOUtils.close(outputStream);
        if (isDelete) {
            file.delete();
        }
    }
}

 * 压缩文件夹
 */
public static void toZip(String inpDir, String outDir,
                         boolean KeepDirStructure) throws RuntimeException, Exception {
    File file = new File(inpDir);
    File[] files = file.listFiles();
    String[] srcDir = new String[files.length];
    for (int i = 0; i < files.length; i++) {
        srcDir[i] = files[i].getAbsolutePath();
    }
    OutputStream out = new FileOutputStream(new File(outDir));
    long start = System.currentTimeMillis();
    ZipOutputStream zos = null;
    try {
        zos = new ZipOutputStream(out);
        List<File> sourceFileList = new ArrayList<File>();
        for (String dir : srcDir) {
            File sourceFile = new File(dir);
            sourceFileList.add(sourceFile);
        }
        compress(sourceFileList, zos, KeepDirStructure);
        //删除临时目录
        deleteToFile(file.getAbsolutePath());
    } catch (Exception e) {
        throw new RuntimeException("zip error from ZipUtils:" + e);
    } finally {
        if (zos != null) {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 * 遍历压缩文件
 */
private static void compress(List<File> sourceFileList, ZipOutputStream zos, boolean KeepDirStructure) throws Exception {
    for (File sourceFile : sourceFileList) {
        String name = sourceFile.getName();
        zipFile(sourceFile, name, zos, KeepDirStructure);
    }
}

 * 压缩文件zipFile
 */

private static void zipFile(File sourceFile, String name, ZipOutputStream zos, boolean KeepDirStructure) throws Exception {
    byte[] buf = new byte[BUFFER_SIZE];
    if (sourceFile.isFile()) {
        zos.putNextEntry(new ZipEntry(name));
        int len;
        FileInputStream in = new FileInputStream(sourceFile);
        while ((len = in.read(buf)) != -1) {
            zos.write(buf, 0, len);
        }

        zos.closeEntry();
        in.close();
    } else {
        File[] listFiles = sourceFile.listFiles();
        if (listFiles == null || listFiles.length == 0) {
            if (KeepDirStructure) {
                zos.putNextEntry(new ZipEntry(name + File.separator));
                zos.closeEntry();
            }
        } else {
            for (File file : listFiles) {
                if (KeepDirStructure) {
                    compress(file, zos, name + File.separator + file.getName(),
                            KeepDirStructure);
                } else {
                    compress(file, zos, file.getName(), KeepDirStructure);
                }
            }
        }
    }
}


 * 解压zip文件
 */
public static void unZipFile(File zipFile, String descDir) throws IOException {
    File pathFile = new File(descDir);
    if (!pathFile.exists()) {
        pathFile.mkdirs();
    }
    //解决zip文件中有中文目录或者中文文件
    ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
    for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
        ZipEntry entry = (ZipEntry) entries.nextElement();
        String zipEntryName = entry.getName();
        InputStream in = zip.getInputStream(entry);
        String outPath = (descDir + File.separator + zipEntryName).replaceAll("\\*", "/");
        /*File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
        if (!file.exists()) {
            file.mkdirs();
        }*/
        //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
        if (new File(outPath).isDirectory()) {
            continue;
        }
        //输出文件路径信息
        System.out.println(outPath);
        OutputStream out = new FileOutputStream(outPath);
        byte[] buf1 = new byte[1024];
        int len;
        while ((len = in.read(buf1)) > 0) {
            out.write(buf1, 0, len);
        }
        in.close();
        out.close();
    }
    zip.close();   //不关闭 无法对压缩包进行删除
    System.out.println("******************解压完毕*******************");
}


** 文件解压缩工具类
 **/
public class ZipFileUtils {

    /**
     * @param zip         zip文件位置
     * @param outputDir   解压缩后文件保存路径
     * @param charsetName 字符编码
     */
    public static void unpack(String zip, String outputDir, String charsetName) {
        unpack(new File(zip), new File(outputDir), charsetName);
    }

    /**
     * @param zip         zip文件位置
     * @param outputDir   解压缩后文件保存路径
     * @param charsetName 字符编码
     */
    public static void unpack(File zip, File outputDir, String charsetName) {

        FileOutputStream out = null;
        InputStream in = null;
        //读出文件数据
        ZipFile zipFileData = null;
        ZipFile zipFile = null;
        try {
            //若目标保存文件位置不存在
            if (outputDir != null) if (!outputDir.exists()) {
                outputDir.mkdirs();
            }
            if (charsetName != null && charsetName != "") {
                zipFile = new ZipFile(zip.getPath(), Charset.forName(charsetName));
            } else {
                zipFile = new ZipFile(zip.getPath(), Charset.forName(EfmEncode.UTF_8));
            }
            //zipFile = new ZipFile(zip.getPath(), Charset.forName(charsetName));
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            //处理创建文件夹
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                String filePath = "";

                if (outputDir == null) {
                    filePath = zip.getParentFile().getPath() + File.separator + entry.getName();
                } else {
                    filePath = outputDir.getPath() + File.separator + entry.getName();
                }
                File file = new File(filePath);
                File parentFile = file.getParentFile();
                if (!parentFile.exists()) {
                    parentFile.mkdirs();
                }
                if (parentFile.isDirectory()) {
                    continue;
                }
            }
            if (charsetName != null && charsetName != "") {
                zipFileData = new ZipFile(zip.getPath(), Charset.forName(charsetName));
            } else {
                zipFileData = new ZipFile(zip.getPath(), Charset.forName(EfmEncode.UTF_8));
            }
            Enumeration<? extends ZipEntry> entriesData = zipFileData.entries();
            while (entriesData.hasMoreElements()) {
                ZipEntry entry = entriesData.nextElement();
                in = zipFile.getInputStream(entry);
                String filePath = "";
                if (outputDir == null) {
                    filePath = zip.getParentFile().getPath() + File.separator + entry.getName();
                } else {
                    filePath = outputDir.getPath() + File.separator + entry.getName();
                }
                File file = new File(filePath);
                if (file.isDirectory()) {
                    continue;
                }
                out = new FileOutputStream(filePath);
                int len = -1;
                byte[] bytes = new byte[1024];
                while ((len = in.read(bytes)) != -1) {
                    out.write(bytes, 0, len);
                }
                out.flush();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
                zipFile.close();
                zipFileData.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

 public static final String LINE_SEPARATOR = System.lineSeparator();

    // 生成xml报文
    public static <T> String createXmlString(List<T> data, String rootName) {
        StringWriter sw = new StringWriter();
        sw.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>").append(LINE_SEPARATOR);
        if (StringUtil.isNotEmpty(rootName)) {
            sw.append("<" + rootName + ">").append(LINE_SEPARATOR);
        }
        if (!data.isEmpty()) {
            Class<?> clz = data.get(0).getClass();
            try {
                JAXBContext context = JAXBContext.newInstance(clz);
                Marshaller m = context.createMarshaller();
                m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
                // 是否省略xm头声明信息
                m.setProperty(Marshaller.JAXB_FRAGMENT, true);
                for (T t : data) {
                    m.marshal(t, sw);
                }
            } catch (JAXBException e) {
                e.printStackTrace();
            }
        }
        if (StringUtil.isNotEmpty(rootName)) {
            sw.append(LINE_SEPARATOR).append("</" + rootName + ">").append(LINE_SEPARATOR);
        }
        sw.append(LINE_SEPARATOR).append(LINE_SEPARATOR);
        return sw.toString();
    }

//MD5加密
 public static String getMD5Str(String str) {
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            System.out.println("NoSuchAlgorithmException caught!");
            System.exit(-1);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] byteArray = messageDigest.digest();
        StringBuffer md5StrBuff = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
            else
                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
        }
        return md5StrBuff.toString();
    }

/**
 * @class:  MailUtil
 * @classdesc:  邮件工具类
 */
public class MailUtil {

    // Spring的邮件工具类,实现了MailSender和JavaMailSender接口
    private JavaMailSenderImpl mailSender;

    /**
     * 初始化邮件发送数据
     * @param host 服务器
     * @param username 发送人
     * @param passwd 发送人密码(授权码)
     */
    public void setInitData(String host, String username, String passwd){
        //创建邮件发送服务器
        mailSender = new JavaMailSenderImpl();
        mailSender.setHost(host);
        //mailSender.setPort(465);
        mailSender.setUsername(username);
        mailSender.setPassword(passwd);
        //加认证机制
        Properties javaMailProperties = new Properties();
        javaMailProperties.put("mail.smtp.auth", true);
        javaMailProperties.put("mail.smtp.starttls.enable", true);
        javaMailProperties.put("mail.smtp.timeout", 5000);
        mailSender.setJavaMailProperties(javaMailProperties);
        if (true) {
            javaMailProperties.setProperty("mail.smtp.port", "465");
            javaMailProperties.setProperty("mail.smtp.ssl.enable", "true");
            javaMailProperties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            javaMailProperties.setProperty("mail.smtp.socketFactory.fallback", "false");
            javaMailProperties.setProperty("mail.smtp.socketFactory.port", "465");
        }
        //("初始化邮件发送信息完成");

    }
    /**
     * 发送普通文本
     * @param email 对方邮箱地址
     * @param subject 主题
     * @param text 邮件内容
     */
    public void simpleMailSend(String email, String subject, String text) {
        //创建邮件内容
        SimpleMailMessage message=new SimpleMailMessage();
        message.setFrom(mailSender.getUsername());
        message.setTo(email);
        message.setSubject(subject);
        message.setText(text);
        //发送邮件
        mailSender.send(message);
        System.out.println("发送成功");
    }

    /**
     * 发送附件,支持多附件
     * //使用JavaMail的MimeMessage,支付更加复杂的邮件格式和内容
     //MimeMessages为复杂邮件模板,支持文本、附件、html、图片等。
     * @param email 对方邮箱
     * @param subject 主题
     * @param text 内容
     * @param paths 附件路径,和文件名
     * @throws MessagingException
     */
    public void attachedSend(String email, String subject, String text, Map<String,String> paths) throws MessagingException {

        MimeMessage message = mailSender.createMimeMessage();
        //创建MimeMessageHelper对象,处理MimeMessage的辅助类
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        //使用辅助类MimeMessage设定参数
        helper.setFrom(mailSender.getUsername());
        helper.setTo(email);
        helper.setSubject(subject);
        helper.setText(text);

        if (paths != null){
            paths.forEach((k, v)->{
                //加载文件资源,作为附件
                FileSystemResource file = new FileSystemResource(v);
                try {
                    //添加附件
                    helper.addAttachment(k, file);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        //发送邮件
        mailSender.send(message);
    }

    /**
     * 发送html文件,支持多图片
     * @param email 对方邮箱
     * @param subject 主题
     * @param text 内容
     * @param paths 富文本中添加用到的路径,一般是图片,或者css,js文件
     * @throws MessagingException
     */
    public void richContentSend(String email, String subject, String text, Map<String, String> paths) throws MessagingException {

        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);

        helper.setFrom(mailSender.getUsername());
        helper.setTo(email);
        helper.setSubject(subject);
        //第二个参数true,表示text的内容为html,然后注意<img/>标签,src='cid:file','cid'是contentId的缩写,'file'是一个标记,
        //需要在后面的代码中调用MimeMessageHelper的addInline方法替代成文件
        helper.setText(text,true);
        //文件地址相对应src目录
        // ClassPathResource file = new ClassPathResource("logo.png");

        if (paths!=null){
            paths.forEach((k, v)->{
                //文件地址对应系统目录
                FileSystemResource file = new FileSystemResource(v);
                try {
                    helper.addInline(k, file);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        mailSender.send(message);
    }

    /**
     * 群发多人,且多附件
     * @param mailto 多人邮件地址
     * @param subject 主题
     * @param text 内容
     * @param filePath 文件路径
     * @throws Exception
     */
    public void sendBatchMailWithFile(String[] emails, String subject, String text, String[] filePath) throws Exception {

        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
        messageHelper.setFrom(new InternetAddress(MimeUtility.encodeText(mailSender.getUsername())));
        messageHelper.setSubject(subject);
        if (filePath != null) {
            BodyPart mdp = new MimeBodyPart();// 新建一个存放信件内容的BodyPart对象
            mdp.setContent(text, "text/html;charset=UTF-8");// 给BodyPart对象设置内容和格式/编码方式
            Multipart mm = new MimeMultipart();// 新建一个MimeMultipart对象用来存放BodyPart对象
            mm.addBodyPart(mdp);// 将BodyPart加入到MimeMultipart对象中(可以加入多个BodyPart)
            // 把mm作为消息对象的内容
            MimeBodyPart filePart;
            FileDataSource filedatasource;
            // 逐个加入附件
            for (int j = 0; j < filePath.length; j++) {
                filePart = new MimeBodyPart();
                filedatasource = new FileDataSource(filePath[j]);
                filePart.setDataHandler(new DataHandler(filedatasource));
                try {
                    filePart.setFileName(MimeUtility.encodeText(filedatasource.getName()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                mm.addBodyPart(filePart);
            }
            mimeMessage.setContent(mm);
        } else {
            messageHelper.setText(text, true);
        }

        List<InternetAddress> list = new ArrayList<InternetAddress>();// 不能使用string类型的类型,这样只能发送一个收件人
        for (int i = 0; i < emails.length; i++) {
            list.add(new InternetAddress(emails[i]));
        }
        InternetAddress[] address = list.toArray(new InternetAddress[list.size()]);

        mimeMessage.setRecipients(Message.RecipientType.TO, address);
        mimeMessage = messageHelper.getMimeMessage();

        mailSender.send(mimeMessage);
    }
}

//HTPP
public class HttpUtil {
    private static Logger LOG = LoggerFactory.getLogger(HttpUtil.class);

    /**
     * post请求
     *
     * @param postURL 请求地址
     * @param content 请求正文
     * @throws IOException
     */
    public static Map<String, Object> syncDataByPost(String postURL, Map<String, String> content) throws Exception {
        Map<String, Object> reason = new HashMap();
        URL postUrl = new URL(postURL);
        HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("POST");
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        connection.setRequestProperty("Content-Type", "application/json");
        connection.connect();
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.write(JSON.toJSONString(content).getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close(); // flush and close
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        String line;
        if ((line = reader.readLine()) != null) {
            Map<String, Object> parse = (Map) JSON.parse(line);
            if ("200".equals(parse.get("code").toString())) {
                LOG.info("同步数据成功====>>>" + parse.get("code").toString());
            } else if ("500".equals(parse.get("code").toString())) {
                LOG.info("同步数据错误====>>>" + parse.get("code").toString());
            }
        }
        reader.close();
        connection.disconnect();
        return reason;
    }

    /**
     * post请求
     *
     * @param postURL 请求地址
     * @param content 请求正文
     * @throws IOException
     */
    public static Map<String, Object> queryDataByPost(String postURL, Map<String, String> content) throws Exception {
        Map<String, Object> reason = new HashMap();
        URL postUrl = new URL(postURL);
        HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("GET");
        connection.setUseCaches(false);
        connection.setInstanceFollowRedirects(true);
        connection.setRequestProperty("Content-Type", "application/json");
        connection.connect();
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        out.write(JSON.toJSONString(content).getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close(); // flush and close
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        String line;
        List<Map<String, Object>> mapList = new ArrayList<>();
        if ((line = reader.readLine()) != null) {
            Map<String, Object> parse = (Map) JSON.parse(line);
            if ("200".equals(parse.get("code").toString())) {
                reason = JSON.parseObject(parse.get("data").toString(), Map.class);
            } else if ("500".equals(parse.get("code").toString())) {
                LOG.info("获取数据错误====>>>" + parse.get("code").toString());
            }
        }
        reader.close();
        connection.disconnect();
        return reason;
    }
}

//未格式化json串转换为格式化的json串
/**
     * 单位缩进字符串。
     */
    private static String SPACE = "   ";


    /**
     * 返回格式化JSON字符串。
     *
     * @param json 未格式化的JSON字符串。
     * @return 格式化的JSON字符串。
     */
    public static String formatJson(String json) {
        StringBuffer result = new StringBuffer();
        int length = json.length();
        int number = 0;
        char key = 0;
        // 遍历输入字符串。
        for (int i = 0; i < length; i++) {
            // 1、获取当前字符。
            key = json.charAt(i);
            // 2、如果当前字符是前方括号、前花括号做如下处理:
            if ((key == '[') || (key == '{')) {
                // (1)如果前面还有字符,并且字符为“:”,打印:换行和缩进字符字符串。
                if ((i - 1 > 0) && (json.charAt(i - 1) == ':')) {
                    result.append('\n');
                    result.append(indent(number));
                }
                // (2)打印:当前字符。
                result.append(key);
                // (3)前方括号、前花括号,的后面必须换行。打印:换行。
                result.append('\n');
                // (4)每出现一次前方括号、前花括号;缩进次数增加一次。打印:新行缩进。
                number++;
                result.append(indent(number));
                // (5)进行下一次循环。
                continue;
            }

            // 3、如果当前字符是后方括号、后花括号做如下处理:
            if ((key == ']') || (key == '}')) {
                // (1)后方括号、后花括号,的前面必须换行。打印:换行。
                result.append('\n');
                // (2)每出现一次后方括号、后花括号;缩进次数减少一次。打印:缩进。
                number--;
                result.append(indent(number));
                // (3)打印:当前字符。
                result.append(key);
                // (4)如果当前字符后面还有字符,并且字符不为“,”,打印:换行。
                if (((i + 1) < length) && (json.charAt(i + 1) != ',')) {
                    result.append('\n');
                }
                // (5)继续下一次循环。
                continue;
            }

            // 4、如果当前字符是逗号。逗号后面换行,并缩进,不改变缩进次数。
            if ((key == ',')) {
                result.append(key);
                result.append('\n');
                result.append(indent(number));
                continue;
            }

            // 5、打印:当前字符。
            result.append(key);
        }
        return result.toString();
    }


    /**
     * 返回指定次数的缩进字符串。每一次缩进三个空格,即SPACE。
     *
     * @param number 缩进次数。
     * @return 指定缩进次数的字符串。
     */
    private static String indent(int number) {
        StringBuffer result = new StringBuffer();
        for (int i = 0; i < number; i++) {
            result.append(SPACE);
        }
        return result.toString();
    }

纯洁的麦兜
18 声望4 粉丝

学习使人进步