MANIFEST.MF文件对Import-Package/Export-Package重排列

众所周知,MANIFEST.MF文件中的空格开头的行是相当于拼接在上一行末尾的。很多又长又乱的Import-Package或者Export-Package,有时候想要搜索某个package却可能被换行截断而搜不到。

这时候咱们可以对它进行格式化重新排列,同时又不影响它的正常运行。再排个序方便查找。

排列前 vs 排列后

附上干货 !!!

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

public class ManifestFormatter {

    private final static String IMPORT_PACKAGE = "Import-Package";
    private final static String EXPORT_PACKAGE = "Export-Package";
    private final static char SEPARATOR = ‘#‘;

    public static void main(String[] args) {
        File mf = new File(args[0]);
        File tmpMf = new File(mf.getParentFile(), "TEMP.MF");
        File backMf = new File(mf.getParentFile(), "MANIFEST.MF.bak");
        if (!mf.exists()) {
            System.out.println(mf.getAbsolutePath() + " is format failed: " + mf.getAbsolutePath() + " is not exits");
            System.exit(2);
        }
        if (backMf.exists()) {
            System.out.println(mf.getAbsolutePath() + " is format failed: " + backMf.getName() + " is exits");
            System.exit(3);
        }
        try (BufferedReader br = new BufferedReader(new FileReader(mf)); BufferedWriter bw = new BufferedWriter(new FileWriter(tmpMf));) {
            StringBuilder fileToString = new StringBuilder();
            char[] chars = new char[1024];
            int len;
            while ((len = br.read(chars, 0, chars.length)) != -1) {
                fileToString.append(new String(chars, 0, len));
            }

            // 转换MANIFEST.MF文件中的属性为单行模式,并保持原来的文档格式
            String lineSeparator = fileToString.indexOf("\r\n") != -1 ? "\r\n" : "\n";
            String formatStr = fileToString.toString().replaceAll(lineSeparator + " ", "");
            ByteArrayInputStream bi = new ByteArrayInputStream(formatStr.getBytes());
            Properties properties = new Properties();
            properties.load(bi);

            // 回写MANIFEST.MF文件,重新写入Import-Package与Export-Package
            List<String> importPackageList = getPackageList(properties.getProperty(IMPORT_PACKAGE));
            List<String> exportPackageList = getPackageList(properties.getProperty(EXPORT_PACKAGE));
            String newImportPackageStr = createNewPackage(importPackageList, IMPORT_PACKAGE, lineSeparator);
            String newExportPackageStr = createNewPackage(exportPackageList, EXPORT_PACKAGE, lineSeparator);
            formatStr = formatStr.replaceAll("Import-Package:.*" + lineSeparator, newImportPackageStr);
            formatStr = formatStr.replaceAll("Export-Package:.*" + lineSeparator, newExportPackageStr);
            bw.write(formatStr);
        } catch (IOException e) {
            System.out.println(mf.getAbsolutePath() + " is format failed: " + e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }
        System.out.println(mf.getAbsolutePath() + " is format successed");
    }

    /**
     * 重新创建Import-Package与Export-Package
     *
     * @param packageList
     * @param packageType
     * @param lineSeparator
     * @return
     */
    private static String createNewPackage(List<String> packageList, String packageType, String lineSeparator) {
        StringBuilder newPackageString = new StringBuilder(packageType).append(":").append(lineSeparator);
        int size = packageList.size();
        for (int i = 0; i < size; i++) {
            newPackageString.append(" ");
            newPackageString.append(packageList.get(i));
            if (i < size - 1) {
                newPackageString.append(",");
            }
            newPackageString.append(lineSeparator);
        }
        return newPackageString.toString();
    }

    /**
     * 单行的Import-Package或Export-Package,转化为list数组
     *
     * @param packageStr  单行的Import-Package或Export-Package
     * @param packageType "Import-Package"或"Export-Package"
     * @return
     */
    private static List<String> getPackageList(String packageStr) {
        boolean isOpenQuotes = false;
        char[] chArr = packageStr.toCharArray();
        int len = chArr.length;
        // 双引号外面的逗号,转为分隔符
        for (int i = 0; i < len; i++) {
            if (chArr[i] == ‘"‘) {
                isOpenQuotes = !isOpenQuotes;
            }
            if (chArr[i] == ‘,‘ && !isOpenQuotes) {
                chArr[i] = SEPARATOR;
            }
        }
        List<String> packageList = Arrays.asList(new String(chArr).split(SEPARATOR + ""));
        Collections.sort(packageList);
        return packageList;
    }

}

原文地址:https://www.cnblogs.com/zhangzongjian/p/11829599.html

时间: 2024-10-05 03:57:14

MANIFEST.MF文件对Import-Package/Export-Package重排列的相关文章

MANIFEST.MF文件全面解析

(一)简介 当我们用Jar命令打完包后,会在根目录下面创建META-INF目录,该目录下面会有一些对该Jar包信息的描述,其中肯定会有一个MANIFEST.MF文件,该文件包含了该Jar包的版本.创建人和类搜索路径等信息,当然如果是可执行Jar包,会包含Main-Class属性,表明Main方法入口.下面是httpclient.jar中的MANIFEST.MF内容: Manifest-Version: 1.0 Implementation-Title: HttpComponents Apache

MANIFEST.MF 文件内容完全详解(转)

打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANIFEST.MF文件的内 容,先来看struts.jar中包含的MANIFEST.MF文件内容: Manifest-Version: 1.0Created-By: Apache Ant 1.5.1Extension-Name: Struts FrameworkSpecification-Title:

JAR包中的MANIFEST.MF文件详解以及编写规范

参考百度百科的解释如下: MANIFEST.MF:这个 manifest 文件定义了与扩展和包相关的数据.单词“manifest”的意思是“显示” 打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录,这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANIFEST.MF文件的内容,先来看struts.jar中包含的MANIFEST.MF文件内容: Manifest-Version: 1.0 Created-

Eclipse导出Jar包 和 MANIFEST.MF文件

Eclipse 导出Jar包,在工程中File-Export-JAR file-Next...-Finish,注意选择自己的程序Main Class,其中Jar包中的MANIFEST.MF文件包含了jar的主程序入口和依赖jar的存放位置等信息. Java -jar  Test.jar 导出Jar包后,如有外部包依赖,还要修改Jar包中的 MANIFEST.MF 文件 Manifest-Version: 1.0 Main-Class: modification.AppFrame Class-Pa

MANIFEST.MF文件详解

Java打包文件(jar文件)中通常会包含清单文件(META-INF/MANIFEST.MF),该文件可以包含主类以及加载类路径等信息. 该文件有着严格的格式要求,甚至一个空格都会引起错误. MANIFEST.MF格式特别需要注意以下几点: 1. 文件中的内容以键值对的形式出现,键值对之间采用"冒号+空格"进行分隔(注意:冒号后的空格必须有,否则格式有错误) 2. 文件每行最多72个字符,可以分多行写.调用多个jar时,可以把调用的jar的路径写到一行,每个用空格隔开.当调用的jar比

Jar文件 META-INF/MANIFEST.MF文件详解

打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANIFEST.MF文件的内 容,先来看struts.jar中包含的MANIFEST.MF文件内容: Manifest-Version: 1.0Created-By: Apache Ant 1.5.1Extension-Name: Struts FrameworkSpecification-Title:

关于java中的MANIFEST.MF 文件内容

打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息.可以简化Java应用程序的打包和发布.其中我们最常用的就是Main-Class和Class-Path了.我们来先看看一个MANIFEST.MF文件的内容 Manifest-Version: 1.0 Created-By: Apache Ant 1.5.1 Extension-Name: Struts Framework

meta-inf文件夹以及MANIFEST.MF文件的作用

meta-inf相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用来配置应用程序.扩展程序.类加载器和服务 manifest.mf文件,在用jar打包时自动生成的. META-INF 存在程序入口相关信息,  我们把MANIFEST中的配置信息进行分类,可以归纳出下面几个大类: 一. 一般属性 1.Manifest-Version 用来定义manifest文件的版本,例如:Manifest-Version: 1.0 2.Created-By 声明该文件的生成者,一般该属性是

jar包的MANIFEST.MF文件

打包可执行jar包时,MANIFEST.MF总是个让人头疼的东西,经常出现这种那种问题. 一个例子: ================================================================================ Manifest-Version: 1.0 Main-Class: test.Main Class-Path: ./ ./lib/commons-collections-3.2.jar ./lib/commons-dbcp-1.2.2.