格式化jd-gui反编译源码的行号
2015-06-24 21:51
597 查看
jd-gui是一个非常好的java反编译工具。但是有一点就是用它导出的java文件与源代码中的行号大部分是对应不上的。jd-gui采用将行号以注释的方式显示出来比如在某行开头有个这个”/* 100 */” 表示这行代码在源代码里的第100行。这样的话我们在没有源文件的时候又希望能够远程调试代码几乎是不可能的,并且对于有代码洁癖的人来说阅读带有这么多无用的注释内容更痛苦了。在这里写了个小工具,将行号尽可能的和源文件的行号对应上,同时删除jd-gui加上的注解。比如你的java文件在D:\test\source下那么会在D:\test\下创建一个”source+当前时间戳”的文件夹,格式化后的代码就在这里面。
package cn.wensiqun.utils; import java.io.File; import java.io.IOException; import java.util.List; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; public class RemoveContentUtil { private static String regex = "\\/\\*[\\p{ASCII}]*?\\*\\/\\s?"; //反编译后的java文件目录 private static String directory = "D:\\TEMP\\sources"; private static String newDirectory = ""; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { start(); } public static void start() throws IOException{ File folder = new File(directory); directory = folder.getCanonicalPath(); File parentFolder = folder.getParentFile(); newDirectory = parentFolder.getCanonicalPath() + "\\" + folder.getName() + System.currentTimeMillis() + "\\"; File[] files = folder.listFiles(); loopFile(files); } public static void loopFile(File[] files) throws IOException{ if(files == null){ return; } for(File f : files){ if(f.isFile()){ if(f.getName().endsWith(".java")){ removeContent(directory, newDirectory, f, true); }else{ removeContent(directory, newDirectory, f, false); } }else{ loopFile(f.listFiles()); } } } public static void removeContent(String oldDir, String newDir, File file, boolean remove) throws IOException{ List<String> lines = FileUtils.readLines(file); String relocationString = relocationLineNumber(lines); String newContent = remove ? relocationString.replaceAll(regex, "") : relocationString; File newFile = new File(file.getCanonicalPath().replace(oldDir, newDir)); FileUtils.write(newFile, newContent); } public static String relocationLineNumber(List<String> lines){ int currentLine = 0; StringBuilder content = new StringBuilder(); for(String line : lines){ currentLine++; int num = readLineNumber(line); if(num != -1){ while(currentLine < num){ currentLine++; content.append(IOUtils.LINE_SEPARATOR); } } content.append(line).append(IOUtils.LINE_SEPARATOR); } //IOUtils.LINE_SEPARATOR; return content.toString(); } private static int readLineNumber(String line){ int start = line.indexOf("/*"); int end = line.indexOf("*/"); if(start > -1 && end > start){ //check is annotation String left = line.substring(end + 2).trim(); if(left.startsWith("@")){ return -1; } String linNum = line.substring(start + 2, end).trim(); try{ return Integer.parseInt(linNum); }catch(NumberFormatException e){ return -1; } } return -1; } }
相关文章推荐
- [leetcode] Unique Paths II
- ios UIView的常用属性
- UITextFiled使用总结
- Kaggle-ValueError: Input contains NaN, infinity or a value too large for dtype('float32').
- 关于 UITextField
- ios UIButton的常用属性
- deque时间复杂度和vector,list比较
- IOS UILabel的常用属性
- Android属性之build.prop生成过程
- [leetcode] Unique Paths
- iOS学习笔记(3)UIButton
- UITextField隐藏键盘的几种方式
- Sicily 1443. Printer Queue
- 解决 Errors running builder 'DeploymentBuilder' on project ' .
- View requires API level 14 (current min is 8): <Switch>
- CSU 1658 IQ of XUEXX’s descendants 矩阵快速幂
- C# WebRequest WebClient Post请求Demo
- ZJU2136 Longest Ordered Subsequence
- iOS下载文件之NSData -UIImage
- UILabel和UITableview自定义分割线