better archive support
This commit is contained in:
parent
c2865750c0
commit
a4dedd1324
@ -735,7 +735,7 @@ public class FileOperations {
|
||||
public static byte[] readFileFromArchive(File archive, String entryPath) throws IOException {
|
||||
String name = archive.getName().toLowerCase();
|
||||
try {
|
||||
if (name.endsWith(".zip") || name.endsWith(".jar")) {
|
||||
if (name.endsWith(".car") || name.endsWith(".zip") || name.endsWith(".jar")) {
|
||||
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(archive))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
@ -817,14 +817,138 @@ public class FileOperations {
|
||||
public static boolean isArchiveFile(String filename) {
|
||||
if (filename == null) return false;
|
||||
String n = filename.toLowerCase();
|
||||
return n.endsWith(".war") || n.endsWith(".zip") || n.endsWith(".jar") || n.endsWith(".tar") || n.endsWith(".tar.gz") || n.endsWith(".tgz") || n.endsWith(".7z") || n.endsWith(".rar");
|
||||
return n.endsWith(".car") || n.endsWith(".war") || n.endsWith(".zip") || n.endsWith(".jar") || n.endsWith(".tar") || n.endsWith(".tar.gz") || n.endsWith(".tgz") || n.endsWith(".7z") || n.endsWith(".rar");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a file can be opened as an archive by actually attempting to read it.
|
||||
* This method does NOT rely on file extension - it always tries to actually
|
||||
* read and parse the file as an archive to verify its contents.
|
||||
*/
|
||||
public static boolean canOpenAsArchive(File file) {
|
||||
if (file == null || !file.exists() || !file.isFile()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Always try to detect format by actually reading the file content
|
||||
// This works for any file regardless of extension
|
||||
return tryDetectArchiveFormat(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to detect the archive format by trying to read the file.
|
||||
* Returns true if the file can be opened as any supported archive format.
|
||||
*/
|
||||
private static boolean tryDetectArchiveFormat(File file) {
|
||||
try {
|
||||
String name = file.getName().toLowerCase();
|
||||
|
||||
// Try ZIP (includes .car, .zip, .jar, .war, and any file with zip magic)
|
||||
if (name.endsWith(".car") || name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war")) {
|
||||
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(file))) {
|
||||
ZipEntry entry = zis.getNextEntry();
|
||||
if (entry != null) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid zip
|
||||
}
|
||||
} else {
|
||||
// Try ZIP for unknown extensions (zip files without extension)
|
||||
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(file))) {
|
||||
ZipEntry entry = zis.getNextEntry();
|
||||
if (entry != null) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid zip
|
||||
}
|
||||
}
|
||||
|
||||
// Try 7z
|
||||
if (name.endsWith(".7z")) {
|
||||
try (SevenZFile szf = new SevenZFile(file)) {
|
||||
SevenZArchiveEntry entry = szf.getNextEntry();
|
||||
if (entry != null) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid 7z
|
||||
}
|
||||
} else {
|
||||
// Try 7z for unknown extensions
|
||||
try (SevenZFile szf = new SevenZFile(file)) {
|
||||
SevenZArchiveEntry entry = szf.getNextEntry();
|
||||
if (entry != null) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid 7z
|
||||
}
|
||||
}
|
||||
|
||||
// Try RAR
|
||||
if (name.endsWith(".rar")) {
|
||||
try (com.github.junrar.Archive rar = new com.github.junrar.Archive(file)) {
|
||||
if (rar.getFileHeaders().size() > 0) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid rar
|
||||
}
|
||||
} else {
|
||||
// Try RAR for unknown extensions
|
||||
try (com.github.junrar.Archive rar = new com.github.junrar.Archive(file)) {
|
||||
if (rar.getFileHeaders().size() > 0) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid rar
|
||||
}
|
||||
}
|
||||
|
||||
// Try TAR/TAR.GZ
|
||||
if (name.endsWith(".tar") || name.endsWith(".tar.gz") || name.endsWith(".tgz")) {
|
||||
try {
|
||||
InputStream is = new FileInputStream(file);
|
||||
if (name.endsWith(".gz") || name.endsWith(".tgz")) {
|
||||
is = new org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream(is);
|
||||
}
|
||||
try (org.apache.commons.compress.archivers.tar.TarArchiveInputStream tais = new org.apache.commons.compress.archivers.tar.TarArchiveInputStream(is)) {
|
||||
org.apache.commons.compress.archivers.tar.TarArchiveEntry entry = tais.getNextTarEntry();
|
||||
if (entry != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid tar
|
||||
}
|
||||
} else {
|
||||
// Try TAR for unknown extensions
|
||||
try {
|
||||
InputStream is = new FileInputStream(file);
|
||||
try (org.apache.commons.compress.archivers.tar.TarArchiveInputStream tais = new org.apache.commons.compress.archivers.tar.TarArchiveInputStream(is)) {
|
||||
org.apache.commons.compress.archivers.tar.TarArchiveEntry entry = tais.getNextTarEntry();
|
||||
if (entry != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
// Not a valid tar
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void searchInArchiveCombined(File archive, String patternLower, Pattern filenameRegex, Pattern contentPattern, boolean caseSensitive, SearchCallback callback) {
|
||||
if (callback != null && callback.isCancelled()) return;
|
||||
String name = archive.getName().toLowerCase();
|
||||
try {
|
||||
if (name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war")) {
|
||||
if (name.endsWith(".car") || name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war")) {
|
||||
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(archive))) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
@ -1037,7 +1161,7 @@ public class FileOperations {
|
||||
|
||||
String name = archive.getName().toLowerCase();
|
||||
try {
|
||||
if (name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war")) {
|
||||
if (name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war") || name.endsWith(".car")) {
|
||||
extractZip(archive, targetDir, callback);
|
||||
} else if (name.endsWith(".7z")) {
|
||||
extract7z(archive, targetDir, callback);
|
||||
@ -1046,7 +1170,40 @@ public class FileOperations {
|
||||
} else if (name.endsWith(".tar") || name.endsWith(".tar.gz") || name.endsWith(".tgz")) {
|
||||
extractTar(archive, targetDir, callback);
|
||||
} else {
|
||||
throw new IOException("Unsupported archive format: " + name);
|
||||
// For unknown extensions, try to detect format by attempting to read
|
||||
// First try ZIP (most common)
|
||||
try {
|
||||
extractZip(archive, targetDir, callback);
|
||||
return; // Success
|
||||
} catch (IOException zipEx) {
|
||||
// Not a zip, try other formats
|
||||
}
|
||||
|
||||
// Try 7z
|
||||
try {
|
||||
extract7z(archive, targetDir, callback);
|
||||
return; // Success
|
||||
} catch (IOException sevenZEx) {
|
||||
// Not a 7z
|
||||
}
|
||||
|
||||
// Try RAR
|
||||
try {
|
||||
extractRar(archive, targetDir, callback);
|
||||
return; // Success
|
||||
} catch (IOException rarEx) {
|
||||
// Not a rar
|
||||
}
|
||||
|
||||
// Try TAR/TAR.GZ
|
||||
try {
|
||||
extractTar(archive, targetDir, callback);
|
||||
return; // Success
|
||||
} catch (IOException tarEx) {
|
||||
// Not a tar
|
||||
}
|
||||
|
||||
throw new IOException("Unsupported or invalid archive format: " + name);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (callback != null) {
|
||||
@ -1066,7 +1223,7 @@ public class FileOperations {
|
||||
}
|
||||
|
||||
String name = archive.getName().toLowerCase();
|
||||
if (!(name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war"))) {
|
||||
if (!(name.endsWith(".car") || name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war"))) {
|
||||
throw new IOException("Unsupported archive format for in-memory zip extraction: " + archive.getName());
|
||||
}
|
||||
|
||||
@ -1282,7 +1439,7 @@ public class FileOperations {
|
||||
public static boolean supportsArchiveRewrite(File archive) {
|
||||
if (archive == null) return false;
|
||||
String name = archive.getName().toLowerCase();
|
||||
return name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war");
|
||||
return name.endsWith(".car") || name.endsWith(".zip") || name.endsWith(".jar") || name.endsWith(".war");
|
||||
}
|
||||
|
||||
public static void rewriteArchiveFromDirectory(File sourceDir, File targetArchive, String password, ProgressCallback callback) throws IOException {
|
||||
|
||||
@ -1162,8 +1162,10 @@ public class FilePanelTab extends JPanel {
|
||||
int row = fileTable.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
FileItem item = (viewMode == ViewMode.BRIEF) ? tableModel.getItemFromBriefLayout(row, briefCurrentColumn) : tableModel.getItem(row);
|
||||
if (item != null && (item.isDirectory() || FileOperations.isArchiveFile(item.getFile()))) {
|
||||
openSelectedItem();
|
||||
if (item != null && !item.isFtp()) {
|
||||
if (item.isDirectory() || (item.getFile() != null && FileOperations.canOpenAsArchive(item.getFile()))) {
|
||||
openSelectedItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
e.consume();
|
||||
@ -2063,7 +2065,7 @@ public class FilePanelTab extends JPanel {
|
||||
|
||||
if (item.getName().equals("..")) {
|
||||
navigateUp();
|
||||
} else if (FileOperations.isArchiveFile(item.getFile())) {
|
||||
} else if (FileOperations.canOpenAsArchive(item.getFile())) {
|
||||
rememberArchiveReturnState(item.getFile());
|
||||
final File archiveFile = item.getFile();
|
||||
|
||||
@ -2097,7 +2099,7 @@ public class FilePanelTab extends JPanel {
|
||||
);
|
||||
} else if (item.isDirectory()) {
|
||||
loadDirectory(item.getFile());
|
||||
} else if (item.getFile().isFile()) {
|
||||
} else if (item.getFile() != null && item.getFile().isFile()) {
|
||||
openFileNative(item.getFile());
|
||||
}
|
||||
}
|
||||
@ -2610,7 +2612,7 @@ public class FilePanelTab extends JPanel {
|
||||
|
||||
if (item.getName().equals("..")) {
|
||||
navigateUp();
|
||||
} else if (FileOperations.isArchiveFile(item.getFile())) {
|
||||
} else if (FileOperations.canOpenAsArchive(item.getFile())) {
|
||||
rememberArchiveReturnState(item.getFile());
|
||||
final File archiveFile = item.getFile();
|
||||
|
||||
@ -2634,7 +2636,7 @@ public class FilePanelTab extends JPanel {
|
||||
);
|
||||
} else if (item.isDirectory()) {
|
||||
loadDirectory(item.getFile());
|
||||
} else if (item.getFile().isFile()) {
|
||||
} else if (item.getFile() != null && item.getFile().isFile()) {
|
||||
openFileNative(item.getFile());
|
||||
}
|
||||
}
|
||||
@ -4882,7 +4884,7 @@ public class FilePanelTab extends JPanel {
|
||||
}
|
||||
};
|
||||
|
||||
if (archiveLower.endsWith(".zip") || archiveLower.endsWith(".jar") || archiveLower.endsWith(".war")) {
|
||||
if (archiveLower.endsWith(".car") || archiveLower.endsWith(".zip") || archiveLower.endsWith(".jar") || archiveLower.endsWith(".war")) {
|
||||
FileOperations.extractZipArchiveFromMemory(archive, tempDir.toFile(), callback);
|
||||
} else {
|
||||
FileOperations.extractArchive(archive, tempDir.toFile(), callback);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user