读取ipa文件info.plist文件粗略版

需求简介:解压ipa文件到当前目录,读取ipa文件下的info.plist,并返回到java界面。

1.最终效果图

 

 

2.项目整体图

 

jar包可以去maven仓库下载

项目工程下载链接

 

只要5积分,小编整了5天的功能哦。

 

3.源代码

3.1创建jar包主入口Main

public class Main {

public static void main(String[] args) throws Exception {

new IpaUI();

}

}

3.2创建IpaUI

主要涉及java.swing的使用,具体可以参考以下链接

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.File;

import javax.swing.JButton;

import javax.swing.JFileChooser;

import javax.swing.JFrame;

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

 

public class IpaUI {

public static JFrame frmIpa;

public JTextArea textArea;

 

public IpaUI() {

// 窗口框架

frmIpa = new JFrame();

frmIpa.setTitle("ipa工具类");

frmIpa.setBounds(600, 300, 500, 400);

frmIpa.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 

// 面板1

JPanel panel = new JPanel();

frmIpa.getContentPane().add(panel, BorderLayout.NORTH);

JButton button = new JButton("选择文件");

// 监听button的选择路径

button.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

JFileChooser jfc = new JFileChooser();

//                                                 jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );

// 显示打开的文件对话框

jfc.showSaveDialog(frmIpa);

try {

// 使用文件类获取选择器选择的文件

File file = jfc.getSelectedFile();//

String content = IpaService.getIpaInfoMap(file.toString());

textArea.setText(content);

} catch (Exception e2) {

JPanel panel3 = new JPanel();

JOptionPane.showMessageDialog(panel3, "没有选中任何文件", "提示", JOptionPane.WARNING_MESSAGE);

}

}

});

panel.add(button);

 

// 可滚动面板

JScrollPane scrollPane = new JScrollPane();

frmIpa.getContentPane().add(scrollPane, BorderLayout.CENTER);

textArea = new JTextArea();

//                textArea.setFont(new Font("黑体",Font.BOLD,15));

scrollPane.setViewportView(textArea);

 

// 面板2

//                                JPanel panel2 = new JPanel();

//                                frmIpa.getContentPane().add(panel2, BorderLayout.SOUTH);

//                                JButton button2 = new JButton("请选择解压路径");

//                                button2.addActionListener(new ActionListener() {

//                                                public void actionPerformed(ActionEvent e) {

//                                                        JFileChooser jfc=new JFileChooser();

////                                                         jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );

//                                                        //显示打开的文件对话框

//                                                         jfc.showSaveDialog(frmIpa);

//                                                        try {

//                                                                //使用文件类获取选择器选择的文件

//                                                                File file = jfc.getSelectedFile();

//                                                                String content = ReadUtils.getIpaInfoMap(file.toString());

//                                                        textArea.setText(content);

//                                                        } catch (Exception e2) {

//                                                                System.out.println("没有选中任何输出路径");

//                                                        }

//                                        }

//                                });

//                                panel2.add(button2);

//全部显示

 

frmIpa.setVisible(true);

}

}

 

3.3创建IpaService

主要涉及dd.plist的使用,

解析ipa/*/info.plist文件。

 

import java.io.File;

import java.util.Map.Entry;

 

import javax.swing.JOptionPane;

import javax.swing.JPanel;

import com.dd.plist.NSArray;

import com.dd.plist.NSDictionary;

import com.dd.plist.NSObject;

import com.dd.plist.PropertyListParser;

 

/**

 * 1.键值对对象,直接添加

 * 2.字典对象,添加键,值递归

 *                 2.1值数组

 *                 2.2值字典

 *                         

 * 3.数组对象,添加键,值判断

 */

public class IpaService {

 

/**

 * 1.生成info.plist文件的键值对

 *

 * @param ipa 输入api文件的路径

 * @return map Info.plist文件中的信息转为键值对 .api文件---->.zip文件---->返回Info.plist

 */

public static String getIpaInfoMap(String ipaPath) {

try {

File Infofile = IpaDao.unZip(ipaPath);

// 解析路径中的文件,封装到map集合

NSDictionary parse = (NSDictionary) PropertyListParser.parse(Infofile);

String infoPlist = digui(parse, -1);

return infoPlist;

} catch (Exception e) {

JPanel panel = new JPanel();

JOptionPane.showMessageDialog(panel, "文件类型不支持", "提示", JOptionPane.WARNING_MESSAGE);

}

return null;

}

 

/**

 * 2.递归方法

 *

 * @param sb

 * @return

 */

public static String digui(NSDictionary parse, int count) {

++count;

StringBuffer sb = new StringBuffer();

for (Entry<String, NSObject> entry : parse.entrySet()) {

// 获取文档键对应的值

String object = entry.getValue().toString();

// 获取文档键

String key = entry.getKey();

// 1.判断是否是其他类型

if (object.contains("NSArray") || object.contains("NSDictionary")) {

 

// 1.1数组类型判断

if (object.contains("NSArray")) {

NSObject[] array = ((NSArray) parse.get(key)).getArray();

// 1.1.1先添加主键

for (int i = 0; i < count; i++) {

sb.append("\t");

}

sb.append(key + ":" + "\r\n");

 

// 1.1.2判断值类型

for (int i = 0; i < array.length; i++) {

//如果是字典类型,继续递归

if (array[i].toString().contains("NSDictionary")) {

NSDictionary parse3 = (NSDictionary) array[i];

String digui2 = digui(parse3, count);

sb.append(digui2);

}

//如果是数值,直接添加

else {

for (int j = 0; j < count; j++) {

sb.append("\t");

}

sb.append("\t" + array[i] + "\r\n");

}

}

}

//1.2字典类型判断

else {

for (int i = 0; i < count; i++) {

sb.append("\t");

}

sb.append(key + ":" + "\r\n");

NSDictionary parse2 = (NSDictionary) parse.get(key);

String digui3 = digui(parse2, count);

sb.append(digui3);

 

}

}

 

// 2.如果是键值对类型直接添加

else {

for (int i = 0; i < count; i++) {

sb.append("\t");

}

sb.append(key + ":" + parse.get(key) + "\r\n");

}

}

return sb.toString();

}

 

}

 

3.4创建IpaDao

主要涉及对javazip的使用,

IO流解压zip文件。

 

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.util.Enumeration;

import java.util.zip.ZipEntry;

import java.util.zip.ZipFile;

/**

 * 解压Zip文件工具类

 */

public class IpaDao {

 

private static final int buffer = 2048;

 

/**

 * 解压Zip文件

 * @param ipaPath 文件目录

 * @throws IOException

 */

public static File unZip(String ipaPath) throws IOException {

int count = -1;

File file = null;

InputStream is = null;

FileOutputStream fos = null;

BufferedOutputStream bos = null;

ZipFile zipFile = null;

File result = null;

 

String savepath = "";

savepath = ipaPath.substring(0, ipaPath.lastIndexOf(".")) + File.separator;

File existsSavePath = new File(savepath); // 创建保存目录

if(existsSavePath.exists()){

existsSavePath.delete();

}

existsSavePath.mkdir();

 

zipFile = new ZipFile(ipaPath); // 解决中文乱码问题

Enumeration<?> entries = zipFile.entries();

while (entries.hasMoreElements()) {

byte buf[] = new byte[buffer];

ZipEntry entry = (ZipEntry) entries.nextElement();

String filename = entry.getName();

boolean ismkdir = false;

// 检查此文件是否带有文件夹

if (filename.lastIndexOf("/") != -1) {

ismkdir = true;

}

filename = savepath + filename;

 // 如果是文件夹先创建

if (entry.isDirectory()) {

file = new File(filename);

file.mkdirs();

continue;

}

file = new File(filename);

// 如果是文件夹先创建

if (!file.exists()) {

if (ismkdir) {

new File(filename.substring(0, filename.lastIndexOf("/"))).mkdirs(); // 目录先创建

}

}

file.createNewFile(); // 创建文件

//判断文件名字

if(filename.endsWith(".app/Info.plist")) {

 result = new File(filename);

}

 

is = zipFile.getInputStream(entry);

fos = new FileOutputStream(file);

bos = new BufferedOutputStream(fos, buffer);

 

while ((count = is.read(buf)) > -1) {

bos.write(buf, 0, count);

}

bos.flush();

bos.close();

fos.close();

 

is.close();

}

zipFile.close();

 

try {

if (bos != null) {

bos.close();

}

if (fos != null) {

fos.close();

}

if (is != null) {

is.close();

}

if (zipFile != null) {

zipFile.close();

}

} catch (Exception e) {

e.printStackTrace();

}

return result;

}

}

 

至此,一个星期的学习工具及使用完毕,感觉思路和学习方法真的重要,在路上浪费了不少思路错误的时间,导致进度缓慢。加油。

 

猜你喜欢

转载自blog.csdn.net/qq_42035966/article/details/82086462