读取压缩war文件中的文件和目录

时间:2015-05-22 14:35:51

标签: java io executable-jar

我正在尝试访问压缩战争存档中的文件夹,但没有成功。

档案结构:

app.war                
       |- META-INF       
       |- org               
       |- WEB-INF             
                   |- classes 
                              |- com       
                              |- static    
                              |- testcases      
                                          |- 1          
                                          |- 2...       
                                          |- ...22      
                                                   |- README.txt (file)
                                                   |- TEST.CASE  (file)

这是我的代码,用于阅读目录 testcases

的内容
URL url = Thread.currentThread().getClass().getClassLoader().getResource("testcases");

LOG.debug("PROTOCOL=" + url.getProtocol());   

List<String> files = IOUtils.readLines(url.openStream());

LOG.debug("DIRS=" + files.size());
LOG.debug("PATH=" + url.getPath());
for (String s : files)
    LOG.debug(s);

在eclipse中运行我得到的输出是:

TestCaseUtil : PROTOCOL=file
TestCaseUtil : DIRS=22
TestCaseUtil : PATH=/C:/Users/{Name}/development/git/app/target/classes/testcases    
TestCaseUtil : 1    
...             
TestCaseUtil : 22

当我从java -jar app.war命令行执行war时,我得到以下输出:

TestCaseUtil : PROTOCOL=jar
TestCaseUtil : DIRS=0
TestCaseUtil : PATH=file:/C:/Users/{Name}/development/git/app/target/app.war!/WEB-INF/classes!/testcases

有人能告诉我我做错了吗?

3 个答案:

答案 0 :(得分:2)

你没有做错任何事。

eclipse中运行项目时,它会将已编译的类文件保留在target文件夹中,而不是实际的war文件结构。

但是当您创建war文件时,所需的类文件将被移动到WEB-INF/classes文件夹下。

因此结果不同。只需确保在创建WAR文件时,其中包含所需的文件夹/类,您可以使用任何ZIP实用程序对其进行验证。

答案 1 :(得分:1)

FileSystem 为zip文件提供虚拟文件系统,但也为类路径资源提供虚拟文件系统。

Map<String,?> env = new HashMap<>();
URL url = getClass().getResource("/META-INF/MANIFEST.MF");

// Correct the URL to either file system or war
{
    String s = url.toString()
        .replaceFirst("/META-INF/MANIFEST.MF", "")
        .replaceFirst("\\!.*$", ""); // In case of war
    url = new URL("jar:" + s); // Use jar:file: ...
}

FileSystem fs = FileSystems.newFileSystem(url.toURI(), env);

Path path = fs.getPath("/WEB-INF/classes/testcases");
Set<FileVisitOption> options = ...
int maxDepth = 1;
FileVisitor<? super Path> visitor = ...
Files.walkFileTree(path, options, maxDepth, visitor);

答案 2 :(得分:0)

这是一个工作代码段(所有功劳都归用户Eggen提供代码库):

Map<String, ?> env = new HashMap<>();
URL url = getClass().getResource("/META-INF/MANIFEST.MF");
LOG.debug("MANIFEST=" + url.toURI());

// Correct the URL to either file system or war
{
    String s = url.toString().replaceFirst("META-INF/MANIFEST.MF", ""); // In case of war
    url = new URL(s); // Use jar:file: ...
    LOG.debug("ARCHIVE=" + url.toURI());
}

FileSystem fs = FileSystems.newFileSystem(url.toURI(), env);
LOG.debug("FILESYSTEM=" + fs.isOpen());

Path path = fs.getPath("/WEB-INF/classes/testcases");
LOG.debug("PATH=" + path.getFileName());

Set<FileVisitOption> options = new HashSet<FileVisitOption>();

int maxDepth = 1;

FileVisitor<Path> visitor = new FileVisitor<Path>() {

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        LOG.debug(file.getFileName());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
        return FileVisitResult.CONTINUE;
    }

};

Files.walkFileTree(path, options, maxDepth, visitor);

预期的产出:

TestCaseUtil      : MANIFEST=jar:file:/C:/Users/{Name}/development/git/app/target/app.war!/META-INF/MANIFEST.MF
TestCaseUtil      : ARCHIVE=jar:file:/C:/Users/{Name}/development/git/app/target/app.war!/
TestCaseUtil      : FILESYSTEM=true
TestCaseUtil      : PATH=testcases
TestCaseUtil      : 1/ 
...
TestCaseUtil      : 22/