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
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)?
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ć!!
Poczytaj o BLOB-ach i CLOBach w MySQL
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!
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??
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
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");
}
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
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??
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??
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
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ć?
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
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)
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
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();
}
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
Nie przyjmuje tej linii:
input+=String.format("%02x",new Byte [] {new Byte(read)});
Nie ma słowa format
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
Skąd mogę pobrać tą wersję nigdzie jej nie widzę ?
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
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?
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
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"
Sorrki pomyliłem się powyżej. Zawartość pliku to: "0x"
w ogóle on w tą pętle while nie wchodzi
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
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.
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