NullPointerException > java.nio.BufferUnderflowException

Cottonwood

Aktives Mitglied
Hi,

wahrscheinlich mal wieder ein Anfängerfehler. Ich sehe einfach nicht, warum hier eine "java.lang.NullPointerException" kommt.

[JAVA=3]import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ReadPDF{

private static boolean testsw;
private static String userPath=System.getProperty("user.home")+System.getProperty("file.separator");
private static long inLength;
private static ByteBuffer[] inBuffer;

public static long read(File in) throws IOException {
testsw=Parameters.retrieveBoolean("ReadPDF.testsw");
FileChannel eingabe=new FileInputStream(in).getChannel();
inLength=0;
if (testsw) ErrorWindow.errorMsg("v0.1 ReadPDF:21 size="+eingabe.size());
try {
inLength=eingabe.read(inBuffer);
} catch (IOException e) {ErrorWindow.errorMsg("v0.1 ReadPDF:24 "+e.toString());
throw e;
} finally {
if (eingabe != null) eingabe.close();
else {
ErrorWindow.errorMsg("v0.1 ReadPDF:29 couldn't open "+in.getAbsolutePath());
ErrorWindow.systemExit(-1);
}
}
return inLength;
}
}
[/code]

Code:
v0.1 ReadPDF:21 size=258968, Thread=main
Exception in thread "main" java.lang.NullPointerException
	at java.nio.channels.FileChannel.read(Unknown Source)
	at de.virginiacity.software.ReadPDF.read(ReadPDF.java:23)
	at de.virginiacity.software.NKAbrech.main(NKAbrech.java:61)
 
Zuletzt bearbeitet:
Meinst du so(?):

[JAVA=3]import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ReadPDF{

private static boolean testsw;
private static String userPath=System.getProperty("user.home")+System.getProperty("file.separator");
private static long inLength;

public static long read(File in) throws IOException {
testsw=Parameters.retrieveBoolean("ReadPDF.testsw");
FileChannel eingabe=new FileInputStream(in).getChannel();
inLength=0;
if (testsw) ErrorWindow.errorMsg("v0.1 ReadPDF:20 size="+eingabe.size());
ByteBuffer[] inBuffer=new ByteBuffer[(int) eingabe.size()];
try {
inLength=eingabe.read(inBuffer);
} catch (IOException e) {ErrorWindow.errorMsg("v0.1 ReadPDF:24 "+e.toString());
throw e;
} finally {
if (eingabe != null) eingabe.close();
else {
ErrorWindow.errorMsg("v0.1 ReadPDF:29 couldn't open "+in.getAbsolutePath());
ErrorWindow.systemExit(-1);
}
}
return inLength;
}
} [/code]

Das klappt leider auch nicht:
Code:
v0.1 ReadPDF:20 size=258968, Thread=main
Exception in thread "main" java.lang.NullPointerException
	at sun.nio.ch.IOUtil.remaining(Unknown Source)
	at sun.nio.ch.IOUtil.read(Unknown Source)
	at sun.nio.ch.FileChannelImpl.read0(Unknown Source)
	at sun.nio.ch.FileChannelImpl.read(Unknown Source)
	at java.nio.channels.FileChannel.read(Unknown Source)
	at de.virginiacity.software.ReadPDF.read(ReadPDF.java:23)
	at de.virginiacity.software.NKAbrech.main(NKAbrech.java:61)
 
Du übergibst ein leeres Array.
Übrigens solltest du, wenn du inLength als Klassenvariable anlegst die Methode synchronisieren, und die ByteBuffers werden nach dem Vorgang nicht mehr verwendet.
 
Du übergibst ein leeres Array.
Ja, da will ich aber doch auch erst rein lesen.
Übrigens solltest du, wenn du inLength als Klassenvariable anlegst die Methode synchronisieren
Warum?
die ByteBuffers werden nach dem Vorgang nicht mehr verwendet.
Das ist richtig. Aber ich habe die ByteBuffers auch nur hier lokal gemacht, um das Problem hier nachvollziehbar zu machen. Eigentlich liegen sie in einem anderen Programm.
 
Ja, da will ich aber doch auch erst rein lesen.

Ich bin den Code gefolgt, und offenbar ist das der Erste Zugriff auf das Array:
Java:
// Iterate over buffers to populate native iovec array.
	int count = offset + length;
	for (int i=offset; i<count; i++) {
		ByteBuffer buf = bufs[i]; //<- Element wird gelesen
		if (buf.isReadOnly())
			throw new IllegalArgumentException("Read-only buffer");
		int pos = buf.position(); //<- Zugriff auf 'null'

Weil so jeder Methodenaufruf auf die selbe Variable zugreift.
 
du willst Daten einlesen, bytes, aber die ByteBuffer-Objekte selber, die im Array enthalten sind, musst du anlegen

> Warum?
stell dir vor zwei Threads arbeiten gleichzeitig die Methode ab, speichern quer durcheinander ihre Ergebnisse in der Variablen,
kommt in normalen Programmen nicht vor, wahrscheinlich nicht wichtig
 
Okay. Das mit dem Synchronisieren habe ich jetzt verstanden.

Ich bin den Code gefolgt, und offenbar ist das der Erste Zugriff auf das Array:
Java:
// Iterate over buffers to populate native iovec array.
	int count = offset + length;
	for (int i=offset; i<count; i++) {
		ByteBuffer buf = bufs[i]; //<- Element wird gelesen
		if (buf.isReadOnly())
			throw new IllegalArgumentException("Read-only buffer");
		int pos = buf.position(); //<- Zugriff auf 'null'
Sorry, aber ich verstehe nicht, was du mir damit sagen willst. Du setzt vielleicht zu viel voraus.

du willst Daten einlesen, bytes, aber die ByteBuffer-Objekte selber, die im Array enthalten sind, musst du anlegen
Wie lege ich den denn an? Kannst du mir da ein Beispiel geben.
 
mit ByteBuffer[] habe ich es noch nie gesehen, kann ich auch nicht finden
Da habe ich wohl zu kompliziert gedacht. Ich habe das jetzt mal auf ByteBuffer (ohne []) umgestellt und es läuft jetzt zumindest mal durch den read:

[JAVA=3]import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ReadPDF{

private static boolean testsw;
private static String userPath=System.getProperty("user.home")+System.getProperty("file.separator");
private static long inLength;

public static long read(File in) throws IOException {
testsw=Parameters.retrieveBoolean("ReadPDF.testsw");
FileChannel eingabe=new FileInputStream(in).getChannel();
inLength=0;
if (testsw) ErrorWindow.errorMsg("v0.1 ReadPDF:20 size()="+eingabe.size());
if (testsw) ErrorWindow.errorMsg("v0.1 ReadPDF:21 position()="+eingabe.position());
int inSize=(int) eingabe.size();
ByteBuffer inBuffer=ByteBuffer.allocate(inSize);
try {
inLength=eingabe.read(inBuffer);
} catch (IOException e) {ErrorWindow.errorMsg("v0.1 ReadPDF:26 "+e.toString());
throw e;
} finally {
if (testsw) ErrorWindow.errorMsg("v0.1 ReadPDF:29 position()="+eingabe.position());
if (eingabe != null) eingabe.close();
else {
ErrorWindow.errorMsg("v0.1 ReadPDF:32 couldn't open "+in.getAbsolutePath());
ErrorWindow.systemExit(-1);
}
}
return inLength;
}
} [/code]

Code:
v0.1 ReadPDF:20 size()=258968, Thread=main
v0.1 ReadPDF:21 position()=0, Thread=main
v0.1 ReadPDF:29 position()=258968, Thread=main

Danke erst mal. Ich teste jetzt damit und wenn's klappt, dann schließe ich den Thread. Sonst melde ich mich wieder.
 
Leider kann ich die gelesenen Daten nicht ausgeben. Ich brauche also hier doch noch einmal Hilfe.
Was mache ich hier falsch? Warum bekomme ich in Zeile 41 eine java.nio.BufferUnderflowException?

[JAVA=3]import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class ReadRTF{

private static boolean testsw;
//private static String userPath=System.getProperty("user.home")+System.getProperty("file.separator");
private static long inLength;

public static long read(File in) throws IOException {
testsw=Parameters.retrieveBoolean("ReadRTF.testsw");
FileChannel eingabe=new FileInputStream(in).getChannel();
inLength=0;
if (testsw) ErrorWindow.errorMsg("v0.1 ReadRTF:19 size()="+eingabe.size());
if (testsw) ErrorWindow.errorMsg("v0.1 ReadRTF:20 position()="+eingabe.position());
int inSize=(int) eingabe.size();

ByteBuffer inBuffer=ByteBuffer.allocate(inSize);
try {
inLength=eingabe.read(inBuffer);
} catch (IOException e) {ErrorWindow.errorMsg("v0.1 ReadRTF:26 "+e.toString());
throw e;
} finally {
if (testsw) ErrorWindow.errorMsg("v0.1 ReadRTF:29 position()="+eingabe.position());
if (eingabe != null) eingabe.close();
else {
ErrorWindow.errorMsg("v0.1 ReadRTF:32 couldn't open "+in.getAbsolutePath());
ErrorWindow.systemExit(-1);
}
}
int inPos=0, inRest=(int) inLength, lineLength=80;
while (inRest>0) {
if (inRest<80L) lineLength=inRest;
byte[] tmp=new byte[lineLength];
if (testsw) ErrorWindow.errorMsg("v0.1 ReadRTF:40 inPos="+inPos+", lineLength="+lineLength);
inBuffer.get(tmp, inPos, lineLength);
System.out.println(tmp);
inRest=inRest-lineLength;
}
return inLength;
}
} [/code]

Code:
v0.1 ReadRTF:19 size()=258968, Thread=main
v0.1 ReadRTF:20 position()=0, Thread=main
v0.1 ReadRTF:29 position()=258968, Thread=main
v0.1 ReadRTF:40 inPos=0, lineLength=80, Thread=main
Exception in thread "main" java.nio.BufferUnderflowException
	at java.nio.HeapByteBuffer.get(Unknown Source)
	at de.virginiacity.software.ReadRTF.read(ReadRTF.java:41)
	at de.virginiacity.software.NKAbrech.main(NKAbrech.java:33)
 
BufferOverlow: Du willst reinschreiben obwohl Buffer schon komplett voll ist.
BufferUnderflow: Du willst etwas aus dem Buffer rausholen oder lesen, obwohl der Buffer leer ist.
 
So weit ist mir das schon klar. Aber warum ist der leer. Die Prints in den Zeilen 20 und 29 zeigen m. E., dass der read in Zeile 25 erfolgreich war. Und wenn das stimmt, dann sollte kein BufferUnderflow kommen.

Was von alledem sehe ich falsch?
 
hast du kein Tutorial zu ByteBuffer außer hier im Forum alles nachzufragen?
ich persönlich kenne die Klasse auch nicht, hab mir jetzt paar Methoden angeschaut und rewind() scheint irgendwas zurückzusetzen,
im Zweifel keine unbekannten Klassen verwenden
 
ich persönlich kenne die Klasse auch nicht, hab mir jetzt paar Methoden angeschaut und rewind() scheint irgendwas zurückzusetzen,
Danke für den Tipp. Das war's. :toll:
Ich verstehe allerdings nicht, warum ein get mit absoluter Position ein rewind voraussetzt.

im Zweifel keine unbekannten Klassen verwenden
Da kann man dann aber Java auch nicht lernen. Dies ist mein 2. Programm. Wenn ich beim 1. Programm keine unbekannten Klassen verwendet hätte, dann wäre ich längst nicht mehr bei Java.???:L

hast du kein Tutorial zu ByteBuffer außer hier im Forum alles nachzufragen?
Irgendwo hast du ja Recht. Man braucht eigentlich kein Forum.:autsch:
 

Neue Themen


Zurück
Oben