Avatar billede aka_aze Nybegynder
10. september 2000 - 18:11 Der er 4 kommentarer

Resume FileOutputStream efter IOException

Programmet skal kunne pakke et antal billeder ned i en zipfil ved hjælp af api\'erne under java.util.zip.*

Det virker også fint, men hvis der er mangel på diskplads skal man ha lov til at ryde op og så pakke videre der hvor den er kommet til. Hvorfor springer programmet over nogle bytes når jeg resumer tråden.

Koden:

/*
* @(#)ZipImage.java    1.0 Beta, 05/09/2000
*
* Copyright 2000 BitExtreme.
* All rights reserved.
*/
package ZipImages;
/**
* Packing of multiple images into Zip-file.
*
* @author  BitExtreme
* @version 1.0 Beta, 05/09/2000
*/
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;

import java.io.BufferedWriter;
import java.io.BufferedOutputStream;

import java.io.FileDescriptor;


import javax.swing.DefaultBoundedRangeModel;

public class ZipImage extends Thread {
  /**
  * This class pack multiple images into a zip-file, whos name is
  * generated from the ordernumber, does not support resume and terminate.
  */
  protected ArrayList                imageList;
  protected int                      imageCount;
  protected String                    orderNumber;
  protected String                    fileName = null;
  protected int                      numberPacked = 0;
  protected boolean                  finnished = false;
  protected File                      zipFile = null;
  protected DefaultBoundedRangeModel  brModel = new DefaultBoundedRangeModel();
  protected boolean                  ioRestart = false;
  protected FileOutputStream          out = null;
  protected ZipOutputStream          zipOut = null;
  protected BufferedOutputStream      bufOut = null;

  public ZipImage(ArrayList imageList,String orderNumber) {
    this.imageList = imageList;
    this.orderNumber = orderNumber;
    this.generateFilename();
    this.imageCount = imageList.size();
  }

  public void run() {
      File fileEntry = null;
      FileInputStream fileEntryIn = null;
      String name = null;

    try {
      zipFile = new File(fileName);
      zipFile.createNewFile();
      out = new FileOutputStream(zipFile);

      zipOut = new ZipOutputStream(out);
      zipOut.setMethod(ZipOutputStream.DEFLATED);  // compress

    } catch (java.io.IOException ioExcep) { // fejl
    }

      // for each file ......
      Iterator i = imageList.iterator();
      numberPacked = 0;
      while (i.hasNext()) {
          try {
            fileEntry = new File((String)i.next());
            name = fileEntry.getName();

            ZipEntry zipEntry = new ZipEntry(name);
            zipEntry.setSize(fileEntry.length());
            zipEntry.setTime(fileEntry.lastModified());

            zipOut.putNextEntry(zipEntry);
            fileEntryIn = new FileInputStream(fileEntry);
          } catch (java.io.FileNotFoundException fileNotFoundExcep) { // fejl
          } catch (java.io.IOException ioExcep) { // fejl
          }
          //System.out.println(\"Start inden Try til BufferedOutputStream\");
          try {
            bufOut = new BufferedOutputStream(zipOut,1048576);
            byte[] buffer = new byte[1048576];
            int numberRead;
            // læs filen og hæld det i buffer, skriv antallet af bytes i numberRead
            //System.out.println(\"Start skrivning, filesize \"+fileEntryIn.available());
            //if (ioRestart) { System.out.println(\"While 1\"); }
            System.out.println(\"START LOOP: \"+fileEntryIn.available());
            boolean pack = true;
            while (pack) {
                try {
                  if (ioRestart) {
                    bufOut.flush();
                    ioRestart = false;
                  }
                  numberRead = fileEntryIn.read(buffer);
                  if (numberRead >= 0) {
                    System.out.println(\"IN LOOP: \"+fileEntryIn.available());
                    // skriv buffer fra 0 til længden ned i zipOut
                    bufOut.write(buffer,0,numberRead);
                  } else {
                    pack = false;
                  }
                } catch (java.util.zip.ZipException zipExcep) { // fejl
                  // ********* zip exception
                  System.out.println(\"ZIP EXCEPTION: \"+zipExcep);
                  this.currentThread().suspend();
                } catch (java.io.IOException ioExcep) { // fejl
                  // *****IO**** skrivefejl (ikke mere plads)
                  System.out.println(\"IN IOEXCEP: \"+fileEntryIn.available());
                  System.out.println(\"IO EXCEPTION: \"+ioExcep);
                  ioRestart = true;
                  this.currentThread().suspend();
                }
            } // while

            fileEntryIn.close();

            zipOut.closeEntry();
            numberPacked++;
            brModel.setValue(numberPacked*100/imageCount);

          } catch (java.io.FileNotFoundException fileNotFoundExcep) { // fejl
          } catch (java.io.IOException ioExcep) { // fejl
          }

      } // while

      try {
        zipOut.finish();
        zipOut.close();
        zipFile = null;
      } catch (java.io.IOException ioExcep) { // fejl

      }
      finnished = true;
      System.out.println(\"Finished writing zipfile.\");
  }

  public DefaultBoundedRangeModel getBRModel() {
    return brModel;
  }

  public String getFilename() {
    return fileName;
  }

  public int getNumberPacked() {
    return numberPacked;
  }

  public String getNumberOfTotalPacked() {
    return String.valueOf(numberPacked)+\"/\"+String.valueOf(imageCount);
  }

  public boolean finnishedPacking() {
    return finnished;
  }

  private void generateFilename() {
    fileName = \"g:\\\\javatest\\\\\" + orderNumber + \".zip\";
  }

}
Avatar billede lbhansen Nybegynder
12. september 2000 - 21:16 #1
Har du prøvet at lade være met at lave en flush() hvis der går noget galt, og lade være med at læse noget nyt, men bare skrive det gamle? fx
if (ioRestart) {
//bufOut.flush();
  ioRestart = false;
}
else
  numberRead = fileEntryIn.read(buffer);
Avatar billede aka_aze Nybegynder
12. september 2000 - 21:44 #2
Det har jeg prøvet, det virker ikke.

Jeg har også prøvet at spole både filen jeg læser fra og zipfilen som jeg skriver tilbage til før hvor det gik galt.

Det har nok noget med den måde hvorpå der skrives. Det kan godt være at dataene bliver komprimeret og så tilskrevet filen på en eller anden skør måde.

Men det kan jeg ikke finde noget om.
Avatar billede lbhansen Nybegynder
12. september 2000 - 22:46 #3
Så et andet alternativ. Det lader til endten at være den interne funktionalitet i BufferedOutputStream, eller i Zip, prøv at skifte JVM. Hvis du kører IBM, prøv sun, eller omvendt. Eller også kan du prøve et forum på www.java.sun.com. Der sidder ofte nogle rimelig hardcore gutter.
Avatar billede aka_aze Nybegynder
13. september 2000 - 11:40 #4
Det vil jeg prøve. Jeg er næsten sikker på at det ZipOutputStream som gør det surt for mig, men der er ikke meget dokumentation at hente.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester