MySQL Befüllen einer MySQL DB mit großen Daten

ElJarno

Bekanntes Mitglied
Hi Leute,
soll in einer MySQL DB Datein speichern und bei bedarf auch wieder auslesen. Mein Code unfktioniert soweit. Jedoch hab ich das Problem dass sobald eine Dtaie ein größe von zirka 15 MB überschreitet der Heap von Java überläuft.

Hier mal meine Methode zum befüllen der DB:
Java:
	private void schreibePDFinDB(String dateiID, String pfad, int offsetDatei, int packetGroesse)
			throws IOException, SQLException {
		int partOffset = 0;
		int partBytesRead = 0;
		int partNr = 0;
		int partGroesse = 0;
		File datei = new File(pfad);
		BufferedInputStream is = new BufferedInputStream(new FileInputStream(datei));
		int bytesLeft = (int) datei.length();

		while (bytesLeft > 0) {
			if (bytesLeft < packetGroesse) {
				partGroesse = bytesLeft;
			} else {
				partGroesse = packetGroesse;
			}

			partNr += 1;
			byte[] bytes = this.liesDatei(is, partOffset, partGroesse);
			ByteArrayInputStream byteInpStr = new ByteArrayInputStream(bytes);
			dbBinaerDaten.writeBinaerDaten(dateiID, partNr, partBytesRead, byteInpStr);
			bytesLeft -= partGroesse;
			partOffset += partGroesse;
		}
	}

Java:
	private byte[] liesDatei(BufferedInputStream is, int offset, int length) throws IOException {
		byte[] bytes = new byte[(int) length];
		int numRead = 0;
		while (offset < bytes.length
				&& (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
			offset += numRead;
		}

		is.close();
		return bytes;
	}

Java:
	public void writeBinaerDaten(String dateiID, int part, int leng, ByteArrayInputStream daten)
			throws SQLException {
		String objid = ObjectID.getOBJID(199);

		java.sql.PreparedStatement ps = this.getConnection().prepareStatement(
				"INSERT into BINAER_DATEN VALUES(?,?,?,?,?)");
		ps.setString(1, objid);
		ps.setString(2, dateiID);
		ps.setInt(3, part);
		ps.setInt(4, leng);
		ps.setBlob(5, daten);
		ps.execute();
	}

Bei der Methode liesDatei(datei, offsetDatei) entsteht noch kein Fehler. Also muss es an der Befüllung der Datenbank liegen.
Falls dies nicht genügt kann ich den Rest noch hinterher werfen.


Gruß Jan
 
S

SlaterB

Gast
hilft ein close() auf das PreparedStatement?
void close()
throws SQLException

Releases this Statement object's database and JDBC resources immediately instead of waiting for this to happen when it is automatically closed. It is generally good practice to release resources as soon as you are finished with them to avoid tying up database resources.

Calling the method close on a Statement object that is already closed has no effect.

Note:When a Statement object is closed, its current ResultSet object, if one exists, is also closed.
?
zu den offengehaltenen Ressourcen könnte auch der ByteArrayInputStream mit dem großen Array gehören

-------

werden die PreparedStatements überhaupt sofort ausgeführt und commited?
kannst du in der Schleife mit einem separaten select nachprüfen, ob die einzelnen DB-Einträge da sind?

wie groß sind überhaupt die Teile, funktioniert 15 MB = 5 * 3MB und gibts bei 20 MB dann die Exception beim 6. oder 7. Teil
oder schon früher?

--------

generell sparender:
lies die Daten nicht in ein Byte-Array sondern übergib an das PreparedStatement ein InputStream einer eigenen Klasse,
die dann je nach Anfrage Daten direkt aus der Datei einliest,

kommt dann im weiteren darauf an, wie das PreparedStatement auf den InputStream zugreift, wenn es auch ein riesiges Array abfragt,
ist vielleicht nichts gewonnen (obwohl dann dieses temporäre Array vielleicht nicht länger gehalten wird, ergo kein Speicherproblem bei mehreren),
wenn es aber in einer Schleife jeweils nur 1 KB Daten lädt, dann sollte die Speicherbelastung gar auch nicht viel höher gehen
 
Zuletzt bearbeitet von einem Moderator:

ElJarno

Bekanntes Mitglied
Also ich hab eine 44 Mb große Test-Datei. Bei 2 MB splitte ich die Datei, dann gibts bei dem 12 Paket die Exception splitte ich bei 2 MB gibts die Excpeption bei dem 23 Paket. Also hat die Paktegröße nicht wirklich was damit zu tun.

generell sparender:
lies die Daten nicht in ein Byte-Array sondern übergib an das PreparedStatement ein InputStream einer eigenen Klasse,
die dann je nach Anfrage Daten direkt aus der Datei einliest,

kommt dann im weiteren darauf an, wie das PreparedStatement auf den InputStream zugreift, wenn es auch ein riesiges Array abfragt,
ist vielleicht nichts gewonnen (obwohl dann dieses temporäre Array vielleicht nicht länger gehalten wird, ergo kein Speicherproblem bei mehreren),
wenn es aber in einer Schleife jeweils nur 1 KB Daten lädt, dann sollte die Speicherbelastung gar auch nicht viel höher gehen

Kannst du mir eine Konkreten Code zeigen wie du das mit dem PreparedStatement meinst.
Zur Info die PreparedStatements werden sofort Commited. Gibts denn ne andere Möglichkeit. Wäre ja interessant damit, wenns beim letztetn Paket Exceptions gibt die vorherigen Pakete nicht gespeichert werden bzw. sowas wie ein rollback durchgeführt wird. Ne Idee?

Trotzdem schon mal danke für die vielen Anregungen

Gruß Jan
 
S

SlaterB

Gast
close() bringt nix?

-------

> bzw. sowas wie ein rollback durchgeführt wird. Ne Idee?

AutoCommit false falls eingeschaltet und am Ende eben kein Commit sondern rollback() oder gar nicht,
kann bei SQL jetzt wenig dazu sagen, nach Tutorials richten

> Kannst du mir eine Konkreten Code zeigen wie du das mit dem PreparedStatement meinst.

einfach einen anderen InputStream übergeben, den zu programmieren ist natürlich eine größere Aufgabe, mit Analyse, wie denn das PreparedStatement darauf zugreift, das werde ich nicht alles schreiben,
kann ich auch kaum ohne es zu testen und habe wie gesagt kein SQL-Zugriff verfügbar,
ganz grob

Java:
class MyStream {

// FileInputStream usw. vorbereiten

@Override
public int read(byte[]) {
  // hier kommt die Anfrage des PreparedStatement
  // hier genau zum richtigen Zeitpunkt genau die gewünschte Anzahl aus der Datei lesen
  // evtl. selber Anfang/ Ende des aktuellen Teils mitzählen und nach genügend Bytes -1 zurückgeben, was Ende signalisiert
  // auch wenn in der Datei noch was drinsteht -> das ist fürs nächste Paket
}


}
 

ElJarno

Bekanntes Mitglied
Wie blöd von mir der Fehler lag nicht beim schreiben in die Datenbank sondern beim wieder heraus holen.;)
Hier mal der Code für das Zusammensetzten der Pakte aus der DB:
Java:
	private void lesePDFausDB(String dateiID, String pfad) throws SQLException, IOException {
		String where = "DATEI_ID = '" + dateiID + "'";
		String sortBy = "PART";
		Vector<Byte> byteDaten = new Vector<Byte>();
		Vector<Vector<Object>> vectorDaten = this.dbBinaerDaten.readBinaerDaten(where, sortBy, 0);
		BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(pfad, true));
		for (Vector<Object> daten : vectorDaten) {
			byte[] bytePart = (byte[]) daten.get(4);
			for (byte by : bytePart) {
				byteDaten.add(by);
			}
		}
		byte[] by = new byte[byteDaten.size()];
		for (int i = 0; i < byteDaten.size(); i++) {
			by[i] = byteDaten.get(i);
		}
		output.write(by);
		output.close();
	}
Kann mir vorstellen dass es an den beiden Schleifen liegt. Vielleicht hast du ja einen anderen Ansatz.
Hier noch der Code zum Einlesen der Pakete aus der DB:
Java:
	public Vector<Vector<Object>> readBinaerDaten(String where, String sortBy, int sortOrder)
			throws SQLException {
		Vector<Vector<Object>> daten = null;
		StringBuffer sqlB = new StringBuffer();
		sqlB.append("select * from BINAER_DATEN ");
		sqlB.append("where ");
		sqlB.append(where);
		sqlB.append(" order by ");
		sqlB.append(sortBy);
		if (sortOrder == 1) {
			sqlB.append(" desc");
		}
		if (!where.contains(";"))
			sqlB.append(";");
		daten = this.readMySQLTable(sqlB.toString());

		return daten;
	}// end of readBlob where
 
S

SlaterB

Gast
nunja, Arbeitsspeicher ist begrenzt wie eine Einkaufstüte,

in letztere passen nicht mehr als 70 Salatköpfe, und ein Java-Programm kann nicht beliebig viele MB an bytes halten,
so ist das Leben,

du kannst einem Java-Programm mehr Speicher zuweisen, statt standardmäßig 64 MB auch paar GB, siehe google

oder du sparst wiederum Speicher, z.B. die byte-Arrays nicht alle gleichzeitig in eine Liste stecken,
sondern immer nur eins lesen, in den Stream schreiben, dann das nächste lesen usw.
 

ElJarno

Bekanntes Mitglied
So habs nun hinbekommen.
Danke noch mal.
Hier noch der Code für spätere Generationen:toll:

Zum schreiben einer Datei in die DB:
Java:
	public void writeBinaerDaten(String dateiID, int packetGroesse, File datei)
			throws SQLException, IOException {
		BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(datei));
		long dateiGroesse = datei.length();
		int partNr = 0;
		if (dateiGroesse <= Integer.MAX_VALUE) {
			int bytesLeft = (int) dateiGroesse;

			while (bytesLeft > 0) {
				String objid = ObjectID.getOBJID(199);

				java.sql.PreparedStatement ps = this.getConnection().prepareStatement(
						"INSERT into BINAER_DATEN VALUES(?,?,?,?,?)");
				ps.setString(1, objid);
				ps.setString(2, dateiID);
				ps.setInt(3, partNr);
				ps.setInt(4, packetGroesse);
				ps.setBinaryStream(5, inputStream, packetGroesse);
				ps.execute();
				ps.close();
				partNr += 1;
				bytesLeft -= packetGroesse;
			}
		} else {
			throw new IOException("Datei ist zu groß! " + datei.getName());
		}

	}

Zum herausholen einer Datei aus der DB und die abschließende Speicherung auf der Festplatte.
Java:
	public void readBinaerDaten(String dateiID, int packetGroesse, File datei) throws SQLException,
			IOException {
		ResultSet resultSet = null;
		StringBuffer sqlB = new StringBuffer();
		byte[] bytes = null;
		BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(datei, false));

		sqlB.append("select DATEN from BINAER_DATEN ");
		sqlB.append("where DATEI_ID = '" + dateiID + "'");
		sqlB.append(" order by PART");
		sqlB.append(";");
		resultSet = this.getStatement().executeQuery(sqlB.toString());

		while (resultSet.next()) {
			bytes = resultSet.getBytes("DATEN");
			output.write(bytes);

		}
		output.close();
		resultSet.close();
	}

Gruß Jan
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
L jTable mit Datenbankwerten befüllen Datenbankprogrammierung 7
OnDemand Column char type, wie befüllen? Datenbankprogrammierung 2
S MySQL Befüllen von mehreren Spalten Datenbankprogrammierung 1
N String Array in While Schleife befüllen Datenbankprogrammierung 2
E Access Datenbank mit Insert befüllen Datenbankprogrammierung 5
E JTable mit Datenbankinhalt befüllen Datenbankprogrammierung 4
GianaSisters MySQL INT Datenbankfeld gar nicht befüllen ?! Datenbankprogrammierung 2
P JTable mit Daten aus MySQL befüllen mit Filterung Datenbankprogrammierung 3
C MySQL Datenbank mit Hibernate befüllen Datenbankprogrammierung 5
M Tabellen gleichzeitig befüllen? Datenbankprogrammierung 3
G JTable befüllen Datenbankprogrammierung 5
B Wie kann ich eine Jtable mit Inhalt einer SQL Abfrage füllen Datenbankprogrammierung 14
D Zweckmäßigkeit einer Schlüsseltabelle Datenbankprogrammierung 4
TH260199 Java-Programm. Probleme bei der Umsetzung von einer Kontaktverwaltung. Datenbankprogrammierung 7
S Variable in main soll mit der generierten Zahl aus einer Methode ausgefüllt werden Datenbankprogrammierung 3
N Oracle SQL - Nächst kleineren Namen2 zu einem Namen aus einer Tabelle Datenbankprogrammierung 3
T Datenbank auf einer Webseite aus einer Exceltabelle erstellen Datenbankprogrammierung 5
D JPA gleiche methode funktioniert an einer Stelle, an der anderen nicht Datenbankprogrammierung 3
nonickatall MySQL Auf neue Datensätze in einer Datenbank reagieren Datenbankprogrammierung 5
B Wie kopieren ich eine Spalte von einer Tabelle in eine andere Tabelle SQLite durch java code? Datenbankprogrammierung 26
P Verbindung zu einer Access Datenbank per Eclipse oder Intellij Datenbankprogrammierung 0
pkm Frage zu Encodingproblem bei einer Datenbankanbindung Datenbankprogrammierung 1
B Frage bei einer SQL Query Datenbankprogrammierung 3
F Mapping einer SQL Abfrage in eine Klasse Datenbankprogrammierung 4
J In einer bestimmten Spalte suchen mit Suchfeld (MS SQL) Datenbankprogrammierung 7
S Verbindung von einer Excel Datei zu Java Datenbankprogrammierung 2
J Sql Anfrage nach einer Zeile beenden Datenbankprogrammierung 6
J Welche Kriterien haben Einfluss auf die Geschwindigkeit einer Datenbank ? Datenbankprogrammierung 4
S Anmelden an einer msql datennbank Datenbankprogrammierung 1
F Auslesen einer .dbf-Datei, Zuordnung Index Datenbankprogrammierung 0
ralfb1105 Oracle Zwei ojdbc Driver in einer Applikation? Datenbankprogrammierung 13
Dimax MySQL Maximale Datenlänge für eine Spalte einer Datenbank in java ermitteln Datenbankprogrammierung 15
Dimax MySQL 10 höchsten Werte aus einer Tabelle ermitteln Datenbankprogrammierung 30
L Speicherverbrauch Java Anwendung mit einer Datenbankanbindung Datenbankprogrammierung 19
temi Wie kann ich "Class" in einer DB speichern? Datenbankprogrammierung 2
F UPDATE - Befehl nur in einer Zeile Datenbankprogrammierung 11
I Oracle Wie ermitteln, welche Benutzer-(!)Tabellen in einer DB sind? Datenbankprogrammierung 1
DaCrazyJavaExpert Derby/JavaDB Wert einer Variable in der Datenbank direkt auf 1 setzten. Datenbankprogrammierung 71
D MySQL Suche nach Max Value in einer Tabelle Datenbankprogrammierung 7
W Daten aus einer Datei von einem VServer auslesen Datenbankprogrammierung 1
F MySQL Wie kann ich in Java Datensätze aus einer MySQL Datenbank gezielt in einzelne Arrays schreiben? Datenbankprogrammierung 9
F Java Objekte in einer Datenbank speichern Datenbankprogrammierung 4
MrSnake Hilfe bei erstellen einer DB Datenbankprogrammierung 12
M Wie übergebe ich Datenbankobjekte aus einer sql-Datenbank einer Java Klasse bzw. Instanz Datenbankprogrammierung 7
Z Finde den Fehler: Daten aus einer Access-Datenbank lesen Datenbankprogrammierung 12
D Aktualisierung einer ListView mit Daten aus MySQL-DB Datenbankprogrammierung 5
E Wie kann man mit einer ID-Spalte über eine Parameterübergabe auf eine Seite verweisen? Datenbankprogrammierung 17
E Warum funktioniert das Erzeugen einer View nicht? Datenbankprogrammierung 1
E Kann man in einer if-Bedingung auch SELECT-Statements überprüfen? Datenbankprogrammierung 23
E Was sind die Vorteile von DB2 im Gegensatz zu einer Oracle-Datenbank? Datenbankprogrammierung 5
E Wie geschieht der konzeptueller Entwurf einer Datenbank Datenbankprogrammierung 1
I SQLite Objekt speichern einer Serialisierter Klasse Datenbankprogrammierung 1
D HSQLDB INSERT INTO in einer For Schleife mit selber ID, machbar? Alternative? Datenbankprogrammierung 7
I Inhalt einer hsqldb anzeigen Datenbankprogrammierung 1
J Realisierung einer DB in Combi mit Java Datenbankprogrammierung 13
Androbin [Serializing] Mehrere Objekte in einer einzigen Datei speichern Datenbankprogrammierung 1
S Auswahl einer Datenbank Datenbankprogrammierung 0
M Derby/JavaDB Speicherplatz einer Zeile bestimmen Datenbankprogrammierung 0
P JPA in einer größeren Java SE Anwendung Datenbankprogrammierung 0
R MySQL Blob aus DB auslesen und einer Tabelle ausgeben Datenbankprogrammierung 7
C H2 Syntax fehler beim erstellen einer Tabelle Datenbankprogrammierung 4
L MySQL Uhrzeit-Format innerhalb einer Tabelle Datenbankprogrammierung 8
2 MySQL Daten aus einer Array auslesen und MySQL Statment erstellen. Datenbankprogrammierung 5
S Derby/JavaDB Probleme beim anlegen einer embedded DB Datenbankprogrammierung 13
E Daten einer SQL-Datenbank aus Combobox in labels schreiben Datenbankprogrammierung 6
M Problem beim Erstellen einer Query Datenbankprogrammierung 7
L Datenbankabfrage mit einer Range Datenbankprogrammierung 3
S Anbindung einer Datenbank an Java Datenbankprogrammierung 7
H ResultSet is closed tritt bei JSF aber nicht bei einer Java-Applikation auf Datenbankprogrammierung 10
eskimo328 Datenbankverbindung ohne Passwort im Quelltext bei einer offline Anwendung Datenbankprogrammierung 14
C unverständliches DB Problem (Es ist kein temporärer Systemtabellenbereich mit einer ausreichenden..) Datenbankprogrammierung 5
A Oracle Update Befehl in Datenbank anhand einer Schleife Datenbankprogrammierung 8
Kenan89 Oracle Daten einer Tabelle in Array speichern Oracle Datenbankprogrammierung 10
S 2 Tabellen zu einer zusammenführen, INSERT INTO Fehler Datenbankprogrammierung 5
D Sperrverfahren in einer Datenbank Datenbankprogrammierung 6
B Feld in einer @Entity als Text speichern Datenbankprogrammierung 5
G Oracle Hibernate M:N-Beziehung mit nur einer vorhandenen Tabelle Datenbankprogrammierung 5
M MySQL Auto-Increment einer custom formatted id? Datenbankprogrammierung 2
F Oracle ResultSet zu einer HashMap<Integer, String[]> Datenbankprogrammierung 6
M DB: Mehrere Zeilen in einer Zeile zusammenführen Datenbankprogrammierung 10
D Probleme bei der Erzeugung einer Tabelle Datenbankprogrammierung 15
D Frage zu potenziellen Leerzeichen in einer Datenbank Datenbankprogrammierung 5
H datantyp einer variable ermittel mit sql Datenbankprogrammierung 3
I Zugriff auf Datenbank nach Erstellen einer Executable Jar Datei verweigert Datenbankprogrammierung 10
S Problem beim Anlegen einer Tabelle Datenbankprogrammierung 5
S Wie überprüfe ich ob die Instanz einer Connection gerade werwendet wird? Datenbankprogrammierung 4
M Ausgabe der Rows mit höchstem Wert X einer Gruppe y,z ? Datenbankprogrammierung 2
L Derby/JavaDB Fehler beim Erstellen einer Tabelle Datenbankprogrammierung 2
turmaline [Hibernate] @OneToOne: Löschen einer referenzierten Instanz Datenbankprogrammierung 2
S ResultSet einer Datenbankabfrage - Nullpointer Exception Datenbankprogrammierung 13
B Aktuellen Stand der Datensätze einer Datenbank anzeigen Datenbankprogrammierung 9
B Die Anzahl der Datensaetze einer Datenbank anzeigen Datenbankprogrammierung 2
T Ablage von Benutzereinstellungen in einer DB Datenbankprogrammierung 7
T Inhalt einer Datenbanktabelle autom. in XML ausgeben Datenbankprogrammierung 7
M Oracle Probleme mit dem anbinden einer Oracle 10g Datenbank Datenbankprogrammierung 27
B MySQL Row und ColumnIndex aus einer JTable (mysqlDb) selectieren Datenbankprogrammierung 18
C Hibernate Liste mit allen Objekten einer Entity Datenbankprogrammierung 17
M Sinnvoller Entwurf einer Java DB-Anwendung Datenbankprogrammierung 2
Airwolf89 Spaltennamen einer Tabelle zurückgeben lassen Datenbankprogrammierung 9
1 Aufruf einer View über Java Gui Datenbankprogrammierung 5

Ähnliche Java Themen

Neue Themen


Oben