IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API standards et tierces Java Discussion :

Problème d'extraction d'un gros fichier 7z


Sujet :

API standards et tierces Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    172
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 172
    Par défaut Problème d'extraction d'un gros fichier 7z
    Bonjour,

    Je cherche à utiliser les API sevenzipjbinding-4.65.1.jar et sevenzipjbinding-AllPlatforms.jar pour extraire des archives .7z.

    Après diverses recherches sur internet, je suis arrivé au code suvant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.RandomAccessFile;
    import java.util.ArrayList;
    import java.util.List;
    import net.sf.sevenzipjbinding.ExtractAskMode;
    import net.sf.sevenzipjbinding.ExtractOperationResult;
    import net.sf.sevenzipjbinding.IArchiveExtractCallback;
    import net.sf.sevenzipjbinding.ISequentialOutStream;
    import net.sf.sevenzipjbinding.ISevenZipInArchive;
    import net.sf.sevenzipjbinding.PropID;
    import net.sf.sevenzipjbinding.SevenZip;
    import net.sf.sevenzipjbinding.SevenZipException;
    import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
     
    public class TestZip {
    	private static String repertoireExtract;
     
    	public static class MyExtractCallback implements IArchiveExtractCallback {
            private ISevenZipInArchive inArchive;
     
            public MyExtractCallback(ISevenZipInArchive inArchive) {this.inArchive = inArchive;}
     
            public ISequentialOutStream getStream(final int index, ExtractAskMode extractAskMode) throws SevenZipException {
                if (extractAskMode != ExtractAskMode.EXTRACT) {
                    return null;
                }
                return new ISequentialOutStream() {
                    public int write(byte[] data) throws SevenZipException {
                        FileOutputStream fos;
                        String fichierDestination="";
                        try {
                            File file = new File((String) inArchive.getProperty(index, PropID.PATH));
                            fichierDestination=repertoireExtract+ file.getName();
                            file = new File(fichierDestination);
                            fos = new FileOutputStream(file);
                            fos.write(data);
                            fos.close();
                        } catch (FileNotFoundException e) {e.printStackTrace();
                        } catch (IOException e) {e.printStackTrace();}
                        System.out.println(fichierDestination+" : "+data.length);
                        return data.length;
                    }
                };
            }
     
            public void prepareOperation(ExtractAskMode extractAskMode) throws SevenZipException {}
            public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {}
            public void setCompleted(long completeValue) throws SevenZipException {}
            public void setTotal(long total) throws SevenZipException {}
        }
     
    	public static void main(String[] args) {
    		RandomAccessFile randomAccessFile = null;
            ISevenZipInArchive inArchive = null;
     
    		repertoireExtract="f:\\Test\\";
    		try {
                randomAccessFile = new RandomAccessFile("f:\\Archive.7z", "r");
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
     
                int count = inArchive.getNumberOfItems();
                List<Integer> itemsToExtract = new ArrayList<Integer>();
                for (int i = 0; i < count; i++) {
                    if (!((Boolean) inArchive.getProperty(i, PropID.IS_FOLDER)).booleanValue()) {
                        itemsToExtract.add(Integer.valueOf(i));
                    }
                }
                int[] items = new int[itemsToExtract.size()];
                int i = 0;
                for (Integer integer : itemsToExtract) {
                    items[i++] = integer.intValue();
                }
                inArchive.extract(items, false, new MyExtractCallback(inArchive));
            } catch (Exception e) {
                System.err.println("Error occurs: " + e);
                System.exit(1);
            } finally {
            	if (inArchive != null) {
            		try {inArchive.close();}
            		catch (SevenZipException e) {}
            	}
                if (randomAccessFile != null) {
                	try {randomAccessFile.close();} 
                	catch (IOException e) {}
                }
            }
    	}
    }
    Mon problème est que si mon archive contient de gros fichiers textes, le fichier qui est extrait n'est pas complet. Je n'optient que la fin du fichier.

    Si quelqu'un peut m'aporter une solution, par avance merci.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Parce que, avec ton code, outre les gros problèmes de perfs à ouvrir et fermer constement le même fichier à chaque appel de write(), tu réécrit le fichier. Donc le fichier ne peux pas être plus grand que le buffer de decodage.

    Faut pas réouvrir le fichier à chaque appel. Faut l'ouvrir une fois au début et le fermer à la fin...

  3. #3
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,
    Citation Envoyé par bbkenny Voir le message
    Mon problème est que si mon archive contient de gros fichiers textes, le fichier qui est extrait n'est pas complet. Je n'optient que la fin du fichier.
    C'est normal : l'implémentation de public int write(byte[] data) throws SevenZipException de ISequentialOutStream, c'est n'importe quoi : elle doit être probablement appelée plusieurs fois, et comme elle recrée un nouveau fichier à chaque fois, le nouveau écrase le précédent et donc tu n'as que le dernier buffer dans le fichier à la fin.

    Regardes les snippets ici...
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    172
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 172
    Par défaut
    Bonjour,

    J'ai modifié ISequentialOutStream comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
            public ISequentialOutStream getStream(final int index, ExtractAskMode extractAskMode) throws SevenZipException {
                if (extractAskMode != ExtractAskMode.EXTRACT) {
                    return null;
                }
                final FileOutputStream fos;
            	String fichierDestination="";
                File file = new File((String) inArchive.getProperty(index, PropID.PATH));
                fichierDestination=repertoireExtract+ file.getName();
                file = new File(fichierDestination);
                try {
                	fos = new FileOutputStream(file);
                	return new ISequentialOutStream() {
                		public int write(byte[] data) throws SevenZipException {
                			try {fos.write(data);} 
                			catch (IOException e) {e.printStackTrace();}
                            return data.length;
                		}
                	};
                } 
                catch (FileNotFoundException e) {return null;}
            }
    Cela résoud bien mon problème d'extraction de gros fichier. Par contre, j'ai un warning car je ne ferme pas fos. Je ne vois pas ou je peux mettre fof.close().

    Si quelqu'un a une idée, par avance merci.

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    En regardant vite fait l'API, on voit différentes méthodes sur le callback : setCompleted() et setTotal() par exemple. La doc n'est pas claire sur le but de ces méthodes, mais tu pourrais tester pour voir laquelle est appelée (si elle l'est) lorsque tout le fichier est extrait (Et mets ta référence sur le FileOutputStream dans la classe pour pouvoir y avoir accès dans l'une de ces méthodes et faire le close).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Dans IArchiveExtractCallback.setOperationResult, comme l'indique la javadoc:

    Set result of extraction operation of the file with index index from last call of getStream(int, ExtractAskMode).

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2004
    Messages
    172
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 172
    Par défaut
    Merci pour les informations.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public static class MyExtractCallback implements IArchiveExtractCallback {
    	private FileOutputStream fos=null;
    	private String fichierDestination;
            private ISevenZipInArchive inArchive;
     
            public MyExtractCallback(ISevenZipInArchive inArchive) {this.inArchive = inArchive;}
     
            public ISequentialOutStream getStream(final int index, ExtractAskMode extractAskMode) throws SevenZipException {
                if (extractAskMode != ExtractAskMode.EXTRACT) {return null;}
                File file = new File((String) inArchive.getProperty(index, PropID.PATH));
                fichierDestination=repertoireExtract+ file.getName();
                file = new File(fichierDestination);
                try {
                	fos = new FileOutputStream(file);
                	return new ISequentialOutStream() {
                		public int write(byte[] data) throws SevenZipException {
                			try {fos.write(data);} 
                			catch (IOException e) {e.printStackTrace();}
                            return data.length;
                		}
                	};
                } 
                catch (FileNotFoundException e) {return null;}
            }
     
            public void prepareOperation(ExtractAskMode extractAskMode) throws SevenZipException {}
            public void setOperationResult(ExtractOperationResult extractOperationResult) throws SevenZipException {
            	if (fos!=null){
            		try {fos.close();} 
            		catch (IOException e) {}
            	}
            }
            public void setCompleted(long completeValue) throws SevenZipException {}
            public void setTotal(long total) throws SevenZipException {}
        }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 09/04/2009, 09h36
  2. extraction d'un gros fichier ifstream::getline
    Par Invité4 dans le forum SL & STL
    Réponses: 5
    Dernier message: 22/01/2009, 15h13
  3. Problème lors d'upload de gros fichiers
    Par Haomaru_91 dans le forum ASP.NET
    Réponses: 5
    Dernier message: 22/05/2007, 17h12
  4. [Upload] Problème upload de gros fichiers avec Firefox
    Par the rootsm@n dans le forum Langage
    Réponses: 12
    Dernier message: 19/02/2006, 20h43
  5. Problème d'extraction d'un fichier zip
    Par njely dans le forum Langage
    Réponses: 4
    Dernier message: 24/05/2005, 22h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo