[JAVA] [MySQL] Zapis pliku do bazy

0

Witam!!!
Mam do zrealizowania pewne zadanko w JAVIE. Jednak natknołem się na pewien problem. Jak zapisać jakiś plik (w tym przypadku obraz w jpg) do bazy danych (MySQL)? Nie ma to być sieżka do pliku tylko to zdjęcie.
Z góry dzięki za pomoc

0

a po co Ci zapisywac zdjecie w bazie? Musiałbyś miec pole typu BLOB. A nie lepiej zapisać w bazie polozenie pliku na serwerze a przy pokazywaniu go wyswietlic go na stronie(w aplikacji)?

0

w zadaniu mam ze baza ma przechowywac m.in. "Zdjecie (binary)". Czyli chyba nie scieżke a ten plik przedstawiony w odpowiedni sposób. Tylko nie wiem jak to zrobić!!

0

Poczytaj o BLOB-ach i CLOBach w MySQL

0

Ok Wiem już co reprezentuje BLOB w bazach danych :-)
A wiecie może jak zapisać takie zdjęcie do bazy?
Zdjęcie wczytuje jako:
ImageIcon image = new ImageIcon("dl.jpg");
jednak jak dam image w poleceniu insert to to nie zadziala!

0

coś takiego wymyśliłem żeby zapisać do bazy fotka:

		FileInputStream input =new FileInputStream("foto.jpg");
		JPEGImageDecoder decoder =JPEGCodec.createJPEGDecoder( input );
		image = decoder.decodeAsBufferedImage();
		input.close();

a następnie wstawiam image do bazy! W bazie chyba zapisuje bo wyswiatla sie ze iles bajtów jest wprowadzonych [BLOB - 183 bajtów].
Tylko nie moge dojść jak odczytaną wartość zapisać z powrotem do pliku!! Może ktoś potrafi?? Jak zrobić konwersje??

1

Nie kombinuj tak.

Odczytaj to co jest w pliku tak po prostu - FileInputStream - bez zadnego kodowania/dekodowania. Zapisz ten strumien bajtow do bazy, a pozniej odczytaj. Baza w zaden sposob nie interpretuje tego co jej wrzucasz jako bloba - to tylko przechowalnik na bajty.

pozdrawiam
johny

0

OK bez kombinowania :-)
Żeby zapisać do bazy robie tak:
FileInputStream image =new FileInputStream("dl.jpg");
a następnie zapis;
A jak odczytać to z bazy?? Coś takiego jak poniżej nie działa (niezgodność typów)

rs = stmt.executeQuery("SELECT * FROM zdjecie");
while (rs.next()){
   FileInputStream odczytane = rs.getString("Zdjecie");
}
0

Sprobuj tak:

rs = stmt.executeQuery("SELECT * FROM zdjecie");
while (rs.next()){
   BufferedInputStream odczytane = rs.getBinaryStream("Zdjecie");
}

ew. tak:

rs = stmt.executeQuery("SELECT * FROM zdjecie");
while (rs.next()){
   BufferedInputStream odczytane = rs.getBlob("Zdjecie").getBinaryStream();
}

Nie jestem pewien, ktore zadziala. Pewnie obydwa :P

pozdrawiam
johny

0

Nadal jest jakiś błąd!!
Wyświetla mi sie taki komunikat:
"Type mismatch: cannot convert from InputStream to BufferedInputStream"
Więc zamieniam to na InputStream i otrzymuje coś takiego:

try {
   rs = stmt.executeQuery("SELECT * FROM zdjecie");
   while (rs.next()){
       InputStream odczytane = rs.getBinaryStream("Zdjecie");
   }
} catch (SQLException e) {
   printStackTrace();
}

Tyle że nie wiem jak to zapisać do pliku z tego InputStream!? A także powinienem to zdjęcie pokazać na palecie i też nie wiem jak przejść ;/ Może jeszcze jakaś rada?

Poprzednio dopóki zdjęcie nie było zapisywane to na panel próbowałem wyrzucić jako:

ImageIcon image = new ImageIcon("foto.jpg");
JLabel jeden = new JLabel(image);

A teraz??

0

Nadal jest jakiś błąd!!
Wyświetla mi sie taki komunikat:
"Type mismatch: cannot convert from InputStream to BufferedInputStream"
Więc zamieniam to na InputStream i otrzymuje coś takiego:

try {
   rs = stmt.executeQuery("SELECT * FROM zdjecie");
   while (rs.next()){
       InputStream odczytane = rs.getBinaryStream("Zdjecie");
   }
} catch (SQLException e) {
   printStackTrace();
}

Tyle że nie wiem jak to zapisać do pliku z tego InputStream!? A także powinienem to zdjęcie pokazać na palecie i też nie wiem jak przejść ;/ Może jeszcze jakaś rada?

Poprzednio dopóki zdjęcie nie było zapisywane to na panel próbowałem wyrzucić jako:

ImageIcon image = new ImageIcon("foto.jpg");
JLabel jeden = new JLabel(image);

A teraz??

0

Maly blad:

rs = stmt.executeQuery("SELECT * FROM zdjecie");
while (rs.next()){
   BufferedInputStream odczytane = new BufferedStream(rs.getBinaryStream("Zdjecie"));
//zapis do pliku i tworzenie tablicy dla ImageIcon
  BufferedOutputStream plik = new BufferedOutputStream(new FileOutputStream("plik.jpg"));
  byte read;
  Vector bytes;
  while((read = odczytane.read())!=-1)
  {
    plik.write(read);
    bytes.add(read);
  }
  plik.close();
  odczytane.close();
  byte[] array = new byte[bytes.size()];
  int i=0;
  while(bytes.size()>0)
    array[i++]=bytes.remove(0);
  ImageIcon obrazek = new ImageIcon(array);
}

Nie gwarantuje, ze dziala, bo pisalem z palca. Ale idea jest jasna. Byc moze da sie zrobic latwiej i bardziej optymalnie, ale tak powinno byc ok. Mozna by po zapisaniu otwierac obrazek z tego pliku wlasnie, ale napisalem tworzenie z tablicy, zebys widzial jak mozna, bez zapisywania.

pozdrawiam
johny

0

linie:
bytes.add(read);
array[i++]=bytes.remove(0);
Zwracają mniej więcej taki komunikat:
"The method add(int, Object) in the type Vector is not applicable for the arguments (byte)"
Więc coś tu jest jeszcze nie tak. A co do pliku to jest on tworzony tyle że nie ma w nim zdjęcia tzn. w przeglądarce pisze że podgląd jest niedostępny i nic. Co to może znaczyć jeszcze co zmienić?

0
edd101 napisał(a)

linie:
bytes.add(read);
array[i++]=bytes.remove(0);
Zwracają mniej więcej taki komunikat:
"The method add(int, Object) in the type Vector is not applicable for the arguments (byte)"
Więc coś tu jest jeszcze nie tak. A co do pliku to jest on tworzony tyle że nie ma w nim zdjęcia tzn. w przeglądarce pisze że podgląd jest niedostępny i nic. Co to może znaczyć jeszcze co zmienić?

No tak...

Sprobuj tak:

rs = stmt.executeQuery("SELECT * FROM zdjecie");
while (rs.next()){
   BufferedInputStream odczytane = new BufferedStream(rs.getBinaryStream("Zdjecie"));
//zapis do pliku i tworzenie tablicy dla ImageIcon
  BufferedOutputStream plik = new BufferedOutputStream(new FileOutputStream("plik.jpg"));
  byte read;
  Vector bytes;
  while((read = odczytane.read())!=-1)
  {
    plik.write(read);
    bytes.add(new Byte(read));
  }
  plik.close();
  odczytane.close();
  byte[] array = new byte[bytes.size()];
  int i=0;
  while(bytes.size()>0)
    array[i++]=((Byte)bytes.remove(0)).byteValue();
  ImageIcon obrazek = new ImageIcon(array);
}

pozdrawiam
johny

0

Tworzony plik ma rozmiar 0. I nadal ma burzące do tych dwóch linii. Jednak program "wymusza" pewne zmiany których dokonuje (zaznaczam pogrubionym) i może tu tkwi problem.

try {
rs = stmt.executeQuery("SELECT * FROM zdjecie");
while (rs.next()){
BufferedInputStream odczytane = new BufferedInputStream(rs.getBinaryStream("Zdjecie"));
//zapis do pliku i tworzenie tablicy dla ImageIcon
BufferedOutputStream plik = new BufferedOutputStream(new FileOutputStream("plik.jpg"));
byte read;
Vector bytes = null;
while((read = (byte) odczytane.read())!=-1)
{
plik.write(read);
bytes.add(new Byte(read));
}
plik.close();
odczytane.close();
byte[] array = new byte[bytes.size()];
int i=0;
while(bytes.size()>0)
array[i++]=((Byte)bytes.remove(0)).byteValue();
ImageIcon obrazek = new ImageIcon(array);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}catch (IOException e2) {
e2.printStackTrace();
}

poniżej lista błedów:

java.lang.NullPointerException
	at Desktop.DBczytaj(Desktop.java:111)  <b><--TO ODNOSI SIĘ DO TEGO bytes.add(new Byte(read));</b>
	at Desktop.actionPerformed(Desktop.java:225)
	at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.awt.Component.processMouseEvent(Unknown Source)
	at java.awt.Component.processEvent(Unknown Source)
	at java.awt.Container.processEvent(Unknown Source)
	at java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.awt.Component.dispatchEvent(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)
0

Trzeba było jeszcze to zmienić:
Vector bytes = new Vector();
Teraz tworzy plik o rozmiarze takim jak w bazie ale plik jest niedostępny w podglądzie. Dlaczego?
Pozdrawiam

0

Zrobiłem podgląd tworzonego pliku a tam jest tylko taki zapis: "java.io.FileInputStream@131303f" więc możę i w bazie jest też to samo i dlatego źle zapisuje?? Do bazy wprowadzam fotke tak:

FileInputStream image;
try {
   image = new FileInputStream("dl.jpg");
   stmt.executeUpdate("INSERT INTO zdjecie (Data, Miejsce, Opis, Zdjecie) VALUES (\""+data+"\", \""+miejsce+"\", \""+opis+"\", \""+image+"\");");
   image.close();
} catch (IOException e) {
   e.printStackTrace();
} catch (SQLException e1) {
   e1.printStackTrace();
}
0
edd101 napisał(a)

Zrobiłem podgląd tworzonego pliku a tam jest tylko taki zapis: "java.io.FileInputStream@131303f" więc możę i w bazie jest też to samo i dlatego źle zapisuje?? Do bazy wprowadzam fotke tak:

FileInputStream image;
try {
   image = new FileInputStream("dl.jpg");
   stmt.executeUpdate("INSERT INTO zdjecie (Data, Miejsce, Opis, Zdjecie) VALUES (\""+data+"\", \""+miejsce+"\", \""+opis+"\", \""+image+"\");");
   image.close();
} catch (IOException e) {
   e.printStackTrace();
} catch (SQLException e1) {
   e1.printStackTrace();
}

Ok. Za tamte bledy przepraszam, ostatnio pisalem w Javie z pol roku temu.

Wstawianie of coz blednie, bo wstawiasz do bazy opis FileInputStream, a nie bajty. Patrzylem jak phpmyadmin wrzuca takie obiekty i z tego wyklulo sie to:

FileInputStream image;
try {
   image = new FileInputStream("dl.jpg");
   byte read;
   String input = "0x";
   while((read=(byte)image.read())!=-1)
      input+=String.format("%02x",new Byte [] {new Byte(read)});
   stmt.executeUpdate("INSERT INTO zdjecie (Data, Miejsce, Opis, Zdjecie) VALUES (\""+data+"\", \""+miejsce+"\", \""+opis+"\", \""+input+"\");");
   image.close();
} catch (IOException e) {
   e.printStackTrace();
} catch (SQLException e1) {
   e1.printStackTrace();
}

pozdrawiam
johny

0

Nie przyjmuje tej linii:
input+=String.format("%02x",new Byte [] {new Byte(read)});
Nie ma słowa format

0
edd101 napisał(a)

Nie przyjmuje tej linii:
input+=String.format("%02x",new Byte [] {new Byte(read)});
Nie ma słowa format

Java 1.5?
Ta metoda wystepuje dopiero od tej wersji.

pozdrawiam
johny

0

Skąd mogę pobrać tą wersję nigdzie jej nie widzę ?

0
edd101 napisał(a)

Skąd mogę pobrać tą wersję nigdzie jej nie widzę ?

A chociazby i stad - JDK 5.0 Update 7: http://java.sun.com/javase/downloads/index.jsp

pozdrawiam
johny

0

Zainstalowałem 1.5, dodałem biblioteki do projektu, zresetowałem kompa i nadal sie czepia do tej linii! Co jeszcze moge robić nie tak?

0
edd101 napisał(a)

Zainstalowałem 1.5, dodałem biblioteki do projektu, zresetowałem kompa i nadal sie czepia do tej linii! Co jeszcze moge robić nie tak?

Sprawdz czy zmienna srodowiskowa PATH wskazuje na katalog tego jdk. win+pause/zaawansowane/zmienne srodowiskowe jesli to windows. Jesli korzystasz ze srodowiska programistycznego to sprawdz w ustawieniach czy korzysta z nowego kompilatora.

pozdrawiam
johny

0

OK juz korzysta 1.5 i sie nie pluje do tej linii.
Ale mimo wszystko po zapisie zdjecia do bazy i z powrotem do pliku z bazy otrzymuje zawartość pliku:
"java.io.FileInputStream@1e63e3d"

0

Sorrki pomyliłem się powyżej. Zawartość pliku to: "0x"

0

w ogóle on w tą pętle while nie wchodzi

0

Juz jestem. Jesli sobie jeszcze nie poradziles to testnij to:

FileInputStream image;
try {
   image = new FileInputStream("dl.jpg");
   int read;
   String input = "0x";
   while((read=image.read())!=-1)
      input+=String.format("%02x",new Byte [] {new Byte((byte)read)});
   stmt.executeUpdate("INSERT INTO zdjecie (Data, Miejsce, Opis, Zdjecie) VALUES (\""+data+"\", \""+miejsce+"\", \""+opis+"\", \""+input+"\");");
   image.close();
} catch (IOException e) {
   e.printStackTrace();
} catch (SQLException e1) {
   e1.printStackTrace();
}

pozdrawiam
johny

0

Witam!!!
Jeszcze sobie nie poradziłem ;/
Po tych poprawkach wydaje mi sie że do bazy dobrze już dodaje (sądze po rozmiarze). Jednak prawdopodbnie zczytanie z bazy nie działa prawidłowo plik jest niedostępny dla podglądu.

0

A zobacz w takim razie co jest w tym pliku, ktory sie zapisuje? Czy jest taki (podobny) jak oryginal, czy tez moze jest tekst taki jak wpisywales - 0x...

pozdrawiam
johny

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.