是否有从Java源文件生成包结构的API

是否有从Java源文件生成包结构的API,java,project-layout,Java,Project Layout,我有一个包含Java源文件的源文件夹。这些Java文件有不同的包。使用javac命令,我可以生成包结构,但是包将包含类文件而不是源文件 是否有任何API可以从Java文件生成包结构并将Java文件放入特定的包中假设您在Windows上,我编写了一个批处理脚本来实现这一点 将下面的内容复制到source.bat中,将source.bat放在找到所有.java文件的同一目录中,然后运行它 @echo off @setlocal enabledelayedexpansion for /f "useb

我有一个包含Java源文件的源文件夹。这些Java文件有不同的包。使用javac命令,我可以生成包结构,但是包将包含类文件而不是源文件


是否有任何API可以从Java文件生成包结构并将Java文件放入特定的包中

假设您在Windows上,我编写了一个批处理脚本来实现这一点

将下面的内容复制到
source.bat
中,将
source.bat
放在找到所有
.java
文件的同一目录中,然后运行它

@echo off
@setlocal enabledelayedexpansion

for /f "usebackq delims=" %%f in (`dir /s /b *.java`) do (
    set file=%%~nxf

    for /f "usebackq delims=" %%p in (`findstr package %%~nxf`) do (
        set package=%%p

        set package=!package:*.java:=!
        set package=!package:package =!
        set package=!package:;=!
        set package=!package:.=\!

        echo Expanding !package!...

        mkdir !package!
        xcopy /f %%~nxf !package!
    )
)

@endlocal
但是,如果您在Unix/Linux上,这里有一个
bash
脚本。我相信这可以用一种更好、更简洁的方式来完成,但它确实有效

#! /bin/bash

for file in *.java
do
    package=`grep -h 'package' $file`
    package=`echo $package | sed 's/package//g'`
    package=`echo $package | sed 's/;//g'`
    package=`echo $package | sed 's/\./\//g'`

    echo Expanding $package...
    mkdir -p $package

    cp $file $package
done

下面是我解决这个问题的方法。它打开java文件,读取包名,生成结构,并将文件复制到该结构。欢迎提出改进建议。:)

公共最终类文件列表{
私人地图包地图;
public void createPackageStructure(字符串sourceDir)引发FileNotFoundException
{
FileListing FileListing=新建FileListing();
File startingDirectory=新文件(sourceDir);
fileListing.packageMap=newhashmap();
List files=fileListing.getFileListing(startingDirectory,fileListing.getPackageMap());
fileListing.moveFiles(fileListing.packageMap);
}
public List getFileListing(文件aStartingDir,Map packageMap)抛出FileNotFoundException
{
validateDirectory(aStartingDir);
列表结果=getFileListingNoSort(aStartingDir,packageMap);
集合。排序(结果);
返回结果;
}
私有列表getFileListingNoSort(文件aStartingDir,Map packageMap)引发FileNotFoundException
{  
列表结果=新建ArrayList();
File[]filesAndDirs=aStartingDir.listFiles();
List filesDirs=Arrays.asList(filesAndDirs);
for(文件:filesDirs)
{
结果.添加(文件);
if(file.isFile())
{
packageMap.put(文件,readPackageName(文件.getAbsolutePath()).replace(“.”,“/”).replace(“;”,“/”);
}
其他的
{
//必须是一个目录
//递归调用!
List deeperList=getFileListingNoSort(文件,packageMap);
结果:addAll(deeperList);
}
}
返回结果;
}
公共字符串readPackageName(字符串文件路径)
{
字符串packageName=null;
弦线;
字符串温度[]=新字符串[2];
BufferedReader br=null;
试一试{
File javaFile=新文件(filePath);
br=新的BufferedReader(新的文件读取器(javaFile));
而((line=br.readLine())!=null)
{
if(行索引(“包”)!=-1)
{
温度=行分割(“”);
打破
}
}
br.close();
}捕获(FileNotFoundException fnfe)
{
fnfe.printStackTrace();
}捕获(ioe异常ioe)
{
ioe.printStackTrace();
}
返回温度[1];
}
公共文件(地图包地图)
{
Set keySet=packageMap.keySet();
迭代器it=keySet.Iterator();
文件源文件、destFile、destDirs;
InputStream in=null;
OutputStream out=null;
字节[]buf=新字节[1024];
内伦;
试一试{
while(it.hasNext())
{
sourceFile=(File)it.next();
destDirs=新文件(“src/”+(String)packageMap.get(sourceFile));
destFile=new File(“src/”+(String)packageMap.get(sourceFile)+“/”+sourceFile.getName());
destDirs.mkdirs();
in=新文件输入流(源文件);
out=新文件输出流(destFile);
而((len=in.read(buf))>0){
out.write(buf,0,len);
}
}
}捕获(FileNotFoundException fnfe)
{
fnfe.printStackTrace();
}捕获(ioe异常ioe)
{
ioe.printStackTrace();
}
}
静态私有void validateddirectory(File-addirectory)引发FileNotFoundException
{
if(aDirectory==null){
抛出新的IllegalArgumentException(“目录不应为null”);
}
如果(!aDirectory.exists()){
抛出新的FileNotFoundException(“目录不存在:“+A目录”);
}
如果(!aDirectory.isDirectory()){
抛出新的IllegalArgumentException(“不是目录:“+a目录”);
}
如果(!aDirectory.canRead()){
抛出新的IllegalArgumentException(“无法读取目录:“+A目录”);
}
}
公共地图getPackageMap()
{
返回此.packageMap;
}
} 

那么您的.java文件的结构是否不正确?这可能是一个愚蠢的问题,但是:为什么?如果您指定的输出文件夹与源文件根文件夹相同,javac将把类文件放在源文件旁边。@ManishSharma这不是OP要问的。我支持@JoachimSauer的推理。为什么一开始它们的结构不正确?上面的结构将作为我目前正在处理的UML图生成器项目的输入。因此,它是具有这种结构的输入。这将一次性完成。@PhilippWendler谢谢。我喜欢一行!
public final class FileListing {

private Map packageMap;


public void createPackageStructure(String sourceDir) throws FileNotFoundException 
{
    FileListing fileListing = new FileListing();
File startingDirectory= new File(sourceDir);

    fileListing.packageMap = new HashMap();
    List<File> files = fileListing.getFileListing(startingDirectory,   fileListing.getPackageMap());

    fileListing.moveFiles(fileListing.packageMap);

}


public List<File> getFileListing(File aStartingDir, Map packageMap) throws   FileNotFoundException 
{
    validateDirectory(aStartingDir);
    List<File> result = getFileListingNoSort(aStartingDir,packageMap);
    Collections.sort(result);
    return result;
}


private List<File> getFileListingNoSort(File aStartingDir, Map packageMap) throws FileNotFoundException 
{  
    List<File> result = new ArrayList<File>();
    File[] filesAndDirs = aStartingDir.listFiles();
    List<File> filesDirs = Arrays.asList(filesAndDirs);

    for(File file : filesDirs) 
    {
       result.add(file); 
       if(file.isFile())
       {
           packageMap.put(file, readPackageName(file.getAbsolutePath()).replace(".", "/").replace(";", "/"));
       }
       else 
       {
           //must be a directory
           //recursive call!
           List<File> deeperList = getFileListingNoSort(file,packageMap);
           result.addAll(deeperList);
       }
    }
return result;
}

public String readPackageName(String filePath)
{
  String packageName=null;
  String line;
  String temp[] = new String[2];
  BufferedReader br=null;
  try{
      File javaFile =  new File(filePath);
      br = new BufferedReader(new FileReader(javaFile));
      while((line=br.readLine())!=null)
      {
          if(line.indexOf("package")!=-1)
          {
              temp = line.split(" ");
              break;
          }
      }
      br.close();

  }catch(FileNotFoundException fnfe)
  {
      fnfe.printStackTrace();
  }catch(IOException ioe)
  {
      ioe.printStackTrace();
  }
  return temp[1];
}

public void moveFiles(Map packageMap)
{
 Set keySet = packageMap.keySet();
 Iterator it = keySet.iterator();
     File sourceFile, destFile, destDirs;
 InputStream in = null;
 OutputStream out = null;
 byte[] buf = new byte[1024];
 int len;

     try{
     while(it.hasNext())
         {
        sourceFile = (File)it.next();
        destDirs = new File("src/"+(String)packageMap.get(sourceFile));
        destFile = new File("src/"+   (String)packageMap.get(sourceFile)+"/"+sourceFile.getName());
        destDirs.mkdirs();
        in = new FileInputStream(sourceFile);
        out = new FileOutputStream(destFile);

        while((len = in.read(buf)) > 0){
            out.write(buf, 0, len);
        }
         }
   }catch(FileNotFoundException fnfe)
   {
       fnfe.printStackTrace();
   }catch(IOException ioe)
   {
       ioe.printStackTrace();
   }
}

static private void validateDirectory (File aDirectory) throws FileNotFoundException 
{
  if (aDirectory == null) {
    throw new IllegalArgumentException("Directory should not be null.");
  }
  if (!aDirectory.exists()) {
    throw new FileNotFoundException("Directory does not exist: " + aDirectory);
  }
  if (!aDirectory.isDirectory()) {
    throw new IllegalArgumentException("Is not a directory: " + aDirectory);
  }
  if (!aDirectory.canRead()) {
    throw new IllegalArgumentException("Directory cannot be read: " + aDirectory);
  }
}

public Map getPackageMap()
{
  return this.packageMap;
}
}