2009-05-18 16 views
0

Ich bekomme eine NPE beim Versuch, eine Bilddatei einzulesen, und ich kann nicht für das Leben von mir herausfinden, warum. Hier ist meine Linie:NullPointerException mit ImageIO.read

BufferedImage source = ImageIO.read(new File(imgPath)); 

imgPath ist grundsätzlich garantiert gültig sein und rechts, bevor es hier wird es kopiert die Datei vom Server. Wenn es diese Zeile trifft, ich diese Stack-Trace erhalten:

Exception in thread "Thread-26" java.lang.NullPointerException 
    at com.ctreber.aclib.image.ico.ICOReader.getICOEntry(ICOReader.java:120) 
    at com.ctreber.aclib.image.ico.ICOReader.read(ICOReader.java:89) 
    at javax.imageio.ImageIO.read(ImageIO.java:1400) 
    at javax.imageio.ImageIO.read(ImageIO.java:1286) 
    at PrintServer.resizeImage(PrintServer.java:981) <---My function 
    <Stack of rest of my application here> 

Auch ist dies in meiner Ausgabe Fenster geworfen:

Kann nicht ICOFile erstellen: Kann nicht Bytes lesen: 2

Ich habe keine Ahnung, was vor sich geht, besonders da der Dateikonstruktor erfolgreich ist. Ich kann anscheinend niemanden finden, der ein ähnliches Problem hatte. Hat jemand Ideen? (Java 5, wenn das einen Unterschied macht)

+0

Woher kommt die ICOReader-Klasse? –

+0

Ich habe das Problem aktualisiert, um die vollständige Stack-Trace mit Standorten usw. zu enthalten. – Morinar

Antwort

2

Ich stöberte etwas mehr und fand heraus, dass Sie angeben können, welcher ImageReader ImageIO es verwenden und auf diese Weise lesen wird. Ich stocherte in unserer Codebase herum und stellte fest, dass wir bereits eine Funktion hatten, GENAU genau das zu tun, was ich hier erreichen wollte. Nur für alle andere, die in ein ähnliches Problem läuft, hier ist der Kern des Codes (ein Teil des Mists wie oben definiert ist, aber das sollte jemand helfen, der versucht, es zu tun):

File imageFile = new File(filename); 
Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByFormatName("jpeg"); 
if (imageReaders.hasNext()) { 
    imageReader = (ImageReader)imageReaders.next(); 
    stream = ImageIO.createImageInputStream(imageFile); 
    imageReader.setInput(stream, true); 
    ImageReadParam param = imageReader.getDefaultReadParam(); 
    curImage = imageReader.read(0, param); 
} 

Danke für die Vorschläge und allen helfen.

0

Haben Sie daran gedacht, dass die Datei einfach beschädigt ist oder dass ImageIO versucht, sie als falschen Dateityp zu lesen?

+0

Das ist ein guter Gedanke, aber die Datei ist definitiv gültig ... Ich kann es in einem Bildbetrachter ziehen und sieht gut aus. Es ist möglich, dass es versucht, es als die falsche Art von Datei zu lesen ... es ist ein JPEG, aber hat keine JPEG-Erweiterung. Könnte das ein Problem sein? – Morinar

1

Der Dateikonstruktor wird fast sicher gelingen, unabhängig davon, ob es auf eine gültige/vorhandene Datei zeigt. Zumindest würde ich überprüfen, ob Ihre zugrunde liegende Datei über die exists()-Methode existiert.

+0

Ich habe die gelesene Zeile innerhalb eines "if file.exists()" Blocks fallen lassen und sie hat es dort hinein geschafft und ist genauso gescheitert. – Morinar

0

Googeln für die ICOReader-Klasse ergibt einen Treffer: IconsFactory von jide-common.
Offenbar hatten sie das gleiche Problem:

// Using ImageIO approach results in exception like this. 
// Exception in thread "main" java.lang.NullPointerException 
//   at com.ctreber.aclib.image.ico.ICOReader.getICOEntry(ICOReader.java:120) 
//   at com.ctreber.aclib.image.ico.ICOReader.read(ICOReader.java:89) 
//   at javax.imageio.ImageIO.read(ImageIO.java:1400) 
//   at javax.imageio.ImageIO.read(ImageIO.java:1322) 
//   at com.jidesoft.icons.IconsFactory.b(Unknown Source) 
//   at com.jidesoft.icons.IconsFactory.a(Unknown Source) 
//   at com.jidesoft.icons.IconsFactory.getImageIcon(Unknown Source) 
//   at com.jidesoft.plaf.vsnet.VsnetMetalUtils.initComponentDefaults(Unknown Source) 

// private static ImageIcon createImageIconWithException(final Class<?> baseClass, final String file) throws IOException { 
//  try { 
//   InputStream resource = 
//     baseClass.getResourceAsStream(file); 
//   if (resource == null) { 
//    throw new IOException("File " + file + " not found"); 
//   } 
//   BufferedInputStream in = 
//     new BufferedInputStream(resource); 
//   return new ImageIcon(ImageIO.read(in)); 
//  } 
//  catch (IOException ioe) { 
//   throw ioe; 
//  } 
// } 

Was haben sie stattdessen tun?

private static ImageIcon createImageIconWithException(
     final Class<?> baseClass, final String file) 
     throws IOException { 
    InputStream resource = baseClass.getResourceAsStream(file); 

    final byte[][] buffer = new byte[1][]; 
    try { 
     if (resource == null) { 
      throw new IOException("File " + file + " not found"); 
     } 
     BufferedInputStream in = new BufferedInputStream(resource); 
     ByteArrayOutputStream out = new ByteArrayOutputStream(1024); 

     buffer[0] = new byte[1024]; 
     int n; 
     while ((n = in.read(buffer[0])) > 0) { 

      out.write(buffer[0], 0, n); 
     } 
     in.close(); 
     out.flush(); 
     buffer[0] = out.toByteArray(); 
    } catch (IOException ioe) { 
     throw ioe; 
    } 

    if (buffer[0] == null) { 
     throw new IOException(baseClass.getName() + "/" + file 
       + " not found."); 
    } 
    if (buffer[0].length == 0) { 
     throw new IOException("Warning: " + file 
       + " is zero-length"); 
    } 

    return new ImageIcon(Toolkit.getDefaultToolkit().createImage(
      buffer[0])); 
} 

So könnte man den gleichen Ansatz versuchen: die rohen Bytes lesen und nutzen Toolkit aus ihnen ein Bild zu erzeugen.

+0

Hmm ... das habe ich gesehen, als ich gegoogelt habe, aber offensichtlich die Quelle auf dieser Seite nicht genau genug gelesen habe, um ihr auskommentiertes Problem und ihre neue Lösung zu sehen. Das sieht sicher so aus, als ob es funktionieren würde, aber es scheint wie viel Code um eine fehlerhafte Zeile zu arbeiten (was mich traurig macht). – Morinar

0

"Es ist ein JPEG, aber hat keine JPEG Erweiterung."

Das könnte es sein.

Es scheint, dass die Bibliothek AC.lib-ICO die NPE wirft. Da diese Bibliothek das Microsoft ICO-Dateiformat lesen soll, könnte ein JPEG ein Problem darstellen.

Betrachten Sie das Format explizit mit einem alternative method.

1

Beachten Sie auch, dass ImageIO.read nicht threadsicher ist (es werden ImageReader s wiederverwendet, die nicht threadsicher sind).

Dies bedeutet, dass Sie nicht mehrere Dateien parallel lesen können. Um das zu tun, müssen Sie sich selbst mit ImageReader befassen.

Verwandte Themen