7zip: Il limite della compressione multi-archivio

👤 Marco e Memore
📅 19 Aprile 2026

7-Zip è uno strumento estremamente potente e leggero, ma la sua interfaccia grafica (GUI) presenta un limite operativo per chi gestisce grandi quantità di dati: non permette di comprimere più elementi in archivi separati con un unico comando.

Attualmente, se selezioni diverse cartelle e utilizzi la funzione standard “Aggiungi all’archivio”, 7-Zip raggrupperà inevitabilmente tutto il contenuto in un unico file finale .7z. Per chi ha la necessità di mantenere l’indipendenza dei file (ad esempio per backup strutturati o invii separati), questo costringe a:

  • Ripetere l’operazione manualmente per ogni singola cartella.
  • Utilizzare stringhe di comando nel terminale, poco pratiche per l’uso quotidiano.

La Soluzione: MemoreArchiver

Per risolvere questa mancanza, abbiamo realizzato MemoreArchiver, un piccolo applicativo grafico in Java che funge da “ponte” per 7-Zip. Questo strumento automatizza il processo, permettendoti di selezionare decine di elementi e trasformarli in altrettanti archivi separati in pochi secondi.

1. Il Codice Java (MemoreArchiver.java)

Copia questo codice in un file di testo e nominalo MemoreArchiver.java.

import javax.swing.*;
import java.awt.*;
import java.io.File;

public class MemoreArchiver extends JFrame {
    private JTextField pathField = new JTextField("C:\\Program Files\\7-Zip\\7z.exe");
    private JComboBox<String> formatBox = new JComboBox<>(new String[]{"7z", "zip"});
    private JTextArea logArea = new JTextArea(15, 55);

    public MemoreArchiver() {
        setTitle("MemoreArchiver - Compressione Separata");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout(10, 10));

        // Pannello Superiore
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
        topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));

        // Riga 1: Percorso 7z
        JPanel row1 = new JPanel(new BorderLayout(5, 0));
        row1.add(new JLabel("Percorso 7z.exe: "), BorderLayout.WEST);
        row1.add(pathField, BorderLayout.CENTER);
        JButton checkButton = new JButton("Verifica");
        checkButton.addActionListener(e -> checkPath());
        row1.add(checkButton, BorderLayout.EAST);

        // Riga 2: Selezione Formato (Risolto problema visibilità testo)
        JPanel row2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
        row2.add(new JLabel("Formato archivio: "));
        
        // Impostiamo una dimensione preferita per evitare i puntini (...)
        formatBox.setPreferredSize(new Dimension(80, 25));
        row2.add(formatBox);

        // Riga 3: Pulsanti Azione
        JPanel row3 = new JPanel(new BorderLayout(5, 0));
        JButton runButton = new JButton("SELEZIONA ELEMENTI E COMPRIMI");
        runButton.setFont(new Font("SansSerif", Font.BOLD, 13));
        runButton.addActionListener(e -> startCompression());
        
        JButton clearButton = new JButton("Pulisci Log");
        clearButton.addActionListener(e -> logArea.setText(""));
        
        row3.add(runButton, BorderLayout.CENTER);
        row3.add(clearButton, BorderLayout.EAST);

        topPanel.add(row1);
        topPanel.add(Box.createVerticalStrut(5));
        topPanel.add(row2);
        topPanel.add(Box.createVerticalStrut(10));
        topPanel.add(row3);
        
        add(topPanel, BorderLayout.NORTH);

        // Pannello Centrale: Log
        logArea.setEditable(false);
        logArea.setBackground(new Color(20, 20, 20));
        logArea.setForeground(new Color(50, 255, 50));
        logArea.setFont(new Font("Consolas", Font.PLAIN, 12));
        logArea.setMargin(new Insets(10, 10, 10, 10));
        
        JScrollPane scrollPane = new JScrollPane(logArea);
        scrollPane.setBorder(BorderFactory.createTitledBorder(null, "Console Attività", 0, 0, null, Color.GRAY));
        add(scrollPane, BorderLayout.CENTER);

        pack();
        setLocationRelativeTo(null);
    }

    private void checkPath() {
        File file = new File(pathField.getText());
        if (file.exists() && file.isFile()) {
            JOptionPane.showMessageDialog(this, "Percorso corretto! 7-Zip è pronto.", "Verifica", JOptionPane.INFORMATION_MESSAGE);
            logArea.append("[INFO]: Connessione a 7z.exe stabilita.\n");
        } else {
            JOptionPane.showMessageDialog(this, "Percorso ERRATO.", "Errore", JOptionPane.ERROR_MESSAGE);
            logArea.append("[ERRORE]: Eseguibile non trovato al percorso indicato.\n");
        }
    }

    private void startCompression() {
        JFileChooser chooser = new JFileChooser();
        chooser.setMultiSelectionEnabled(true);
        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            File[] targets = chooser.getSelectedFiles();
            String exePath = pathField.getText();
            String selectedFormat = (String) formatBox.getSelectedItem();

            if (!new File(exePath).exists()) {
                JOptionPane.showMessageDialog(this, "Controlla il percorso di 7-Zip!", "Errore", JOptionPane.ERROR_MESSAGE);
                return;
            }

            new Thread(() -> {
                logArea.append("\n--- NUOVA SESSIONE (" + selectedFormat.toUpperCase() + ") ---\n");
                for (File target : targets) {
                    compress(target, exePath, selectedFormat);
                }
                logArea.append("--- OPERAZIONE CONCLUSA ---\n");
            }).start();
        }
    }

    private void compress(File target, String exePath, String format) {
        try {
            String outputName = target.getAbsolutePath() + "." + format;
            logArea.append("Processing: " + target.getName() + "\n");
            
            ProcessBuilder pb = new ProcessBuilder(exePath, "a", "-t" + format, outputName, target.getAbsolutePath());
            Process p = pb.start();
            p.waitFor();
            
            logArea.append("DONE -> " + outputName + "\n");
            logArea.setCaretPosition(logArea.getDocument().getLength());
        } catch (Exception ex) {
            logArea.append("!!! FAIL: " + target.getName() + " (" + ex.getMessage() + ")\n");
        }
    }

    public static void main(String[] args) {
        try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) {}
        SwingUtilities.invokeLater(() -> new MemoreArchiver().setVisible(true));
    }
}

2. Il Lanciatore Batch (AvviaArchiviatore.bat)

Salva questo codice in un file chiamato AvviaArchiviatore.bat nella stessa cartella del file Java. Si occuperà di tutto lui: compilazione ed esecuzione.

@echo off
cd /d "%~dp0"

echo [Memore] Inizializzazione...

:: Verifica esistenza classe e compilazione automatica
if not exist "MemoreArchiver.class" (
    echo Compilazione di MemoreArchiver.java in corso...
    javac MemoreArchiver.java
    if errorlevel 1 (
        echo Errore: Assicurati che il JDK di Java sia installato e configurato.
        pause
        exit
    )
)

:: Avvio dell'applicazione
echo Apertura interfaccia grafica...
java -cp . MemoreArchiver

:: Gestione errori in uscita
if %errorlevel% neq 0 (
    echo Il programma si e arrestato in modo anomalo.
    pause
)

Come procedere

  1. Crea una cartella e inserisci i due file appena creati.
  2. Lancia AvviaArchiviatore.bat.
  3. Usa l’interfaccia per selezionare tutti i file o le cartelle che desideri (puoi fare una selezione multipla tenendo premuto Ctrl o Shift).
  4. Il programma genererà automaticamente un archivio .7z o .zip per ogni singolo elemento selezionato.

Una volta compilato la prima volta, il file .class rimarrà lì e i successivi avvii saranno istantanei. Se modifichi il codice Java, cancella il file .class e lo script lo ricompilerà automaticamente al prossimo avvio.