如何在Kotlin中获取resources文件夹下的所有文件?
Extract All Contents from Resources'
/folder to External Directory Got it, let's break down how to extract everything inside the /folder directory from your application's resources to an external directory. This solution works for both development environments (where resources are on the local filesystem) and packaged JAR files.
Core Approach
The main challenge is handling two common scenarios:
- Development mode: Your resources are actual files on the filesystem, so you can traverse them directly.
- Packaged JAR: Resources are embedded inside the JAR, so you need to read entries from the JAR file and copy them to the external directory.
Step-by-Step Implementation
Here's a reusable utility method that covers both cases, with clean resource management and structure preservation:
import java.io.*; import java.net.URI; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class ResourceFolderExtractor { public static void extractResourcesFolder(String resourceFolderPath, String targetDirPath) throws IOException { // Create target directory (and parent folders if needed) Path targetDirectory = Paths.get(targetDirPath); Files.createDirectories(targetDirectory); // Get classloader to access resources (more flexible than class-specific getResource) ClassLoader classLoader = ResourceFolderExtractor.class.getClassLoader(); URL folderUrl = classLoader.getResource(resourceFolderPath); if (folderUrl == null) { throw new FileNotFoundException("Resource folder not found: " + resourceFolderPath); } String protocol = folderUrl.getProtocol(); if ("file".equals(protocol)) { // Handle filesystem resources (typical in development) Path sourceFolder = Paths.get(folderUrl.toURI()); Files.walk(sourceFolder) .filter(Files::isRegularFile) // Skip directories, only copy files .forEach(sourceFile -> { try { // Preserve subdirectory structure relative to the source folder Path relativePath = sourceFolder.relativize(sourceFile); Path targetFile = targetDirectory.resolve(relativePath); Files.copy(sourceFile, targetFile); } catch (IOException e) { throw new UncheckedIOException("Failed to copy file: " + sourceFile, e); } }); } else if ("jar".equals(protocol)) { // Handle embedded resources in a JAR file String jarFullPath = folderUrl.getPath().substring(5, folderUrl.getPath().indexOf('!')); try (JarFile jar = new JarFile(new URI(jarFullPath).getPath())) { Enumeration<JarEntry> jarEntries = jar.entries(); while (jarEntries.hasMoreElements()) { JarEntry entry = jarEntries.nextElement(); String entryName = entry.getName(); // Only process entries inside the target resource folder (skip directories) if (entryName.startsWith(resourceFolderPath) && !entry.isDirectory()) { // Calculate relative path to keep subfolder structure intact String relativeEntryPath = entryName.substring(resourceFolderPath.length()); Path targetFile = targetDirectory.resolve(relativeEntryPath); // Create parent directories for nested files Files.createDirectories(targetFile.getParent()); // Copy the entry content to the external file try (InputStream in = jar.getInputStream(entry); OutputStream out = Files.newOutputStream(targetFile)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } } } } } else { throw new UnsupportedOperationException("Unsupported resource protocol: " + protocol); } } // Example usage public static void main(String[] args) throws IOException { // Extract "/folder" from resources to "./external-output-folder" extractResourcesFolder("folder/", "./external-output-folder"); } }
Key Details to Keep in Mind
- Resource Path Format: Always pass the resource folder path with a trailing slash (like
"folder/") to ensure we're targeting the directory, not a file with a matching name. - Structure Preservation: The code maintains the subdirectory structure inside
/folderwhen copying to the external directory, so nested files/folders stay organized. - Resource Safety: Try-with-resources statements are used to auto-close streams and JAR files, preventing resource leaks.
- ClassLoader Flexibility: Using
ClassLoaderinstead ofApplication::class.java.getResourceAsStreamworks better for directory access, especially in modular Java applications.
Troubleshooting Tips
- If you get a
FileNotFoundException, double-check that your/folderis correctly placed in theresourcesdirectory (e.g.,src/main/resourcesfor Maven/Gradle) and included in your build output. - For packaged JARs, verify your build tool isn't excluding the
/foldercontents from the final JAR. - Permission errors? Ensure the target directory has write access for your application process.
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

