Imagem com BLOB, Nunca cria exatamente o mesmo arquivo. Falta pouco

4 respostas
gregowbr

Esse é o código que eu tento utilizar:

package testes;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class BlobSample {
    public static void main(String[] args) throws Exception, IOException, SQLException {
      
        Connection conn = Conexao.pegarConexao();
        String INSERT_PICTURE = "insert into pictures(id, name, photo) values (?, ?, ?)";

        FileInputStream fis = null;
        PreparedStatement ps = null;
        try {
            //save image as blob
            conn.setAutoCommit(false);
            File file = new File("C:\\foto_original.jpg");
            fis = new FileInputStream(file);
            ps = conn.prepareStatement(INSERT_PICTURE);
            ps.setString(1, "2");
            ps.setString(2, "foto_original");
            ps.setBinaryStream(3, fis, (int) file.length());
            ps.executeUpdate();
            conn.commit();

            //read back
            String SELECT_PICTURE = "select id, name, photo from pictures";
            ps = conn.prepareStatement(SELECT_PICTURE);
            ResultSet rs =  ps.executeQuery();
            while (rs.next()) {
                //save blob as an image
                FileOutputStream fos = new FileOutputStream("C:\\foto_modified.jpg");
                //String id = rs.getString(1);
                //String name = rs.getString(2);
                InputStream is  = rs.getBinaryStream(3);
                byte[] buf = new byte[3000];
                int read = 0;
                while ((read = is.read(buf)) > 0) {
                    fos.write(buf, 0, read);
                }
                fos.close();
                is.close();
            }

        } finally {
            ps.close();
            fis.close();
        }
    }
}

Bom o arquivo original tem 50.5 KB e quando o arquivo depois de lido armazenado no banco de dados MySQL como BloB, ele escreve o arquivo de volta, só que quando ele escreve o novo arquivo, esse arquivo fica com 50.1 KB e a imagem obviamente não visualiza.

Alguem sabe como fazer pra ele ficar perfeito? Tudo original? Sem nenhuma perda de dados?
Obrigado!

4 Respostas

yorgan

Eu sempre converto para bytes o arquivo para depois persistir.
Fiz umas alterações no seu código, veja se funciona:

package testes;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class BlobSample {
    public static void main(String[] args) throws Exception, IOException, SQLException {
      
        Connection conn = Conexao.pegarConexao();
        String INSERT_PICTURE = "insert into pictures(id, name, photo) values (?, ?, ?)";

        FileInputStream fis = null;
        PreparedStatement ps = null;
        try {
            //save image as blob
            conn.setAutoCommit(false);
            File file = new File("C:\\foto_original.jpg");
            fis = new FileInputStream(file);
            ps = conn.prepareStatement(INSERT_PICTURE);
            ps.setString(1, "2");
            ps.setString(2, "foto_original");
            ps.setBytes(3, getBytesFromFile());  //Eu utilizo o método setBytes();
            ps.executeUpdate();
            conn.commit();

            //read back
            String SELECT_PICTURE = "select id, name, photo from pictures";
            ps = conn.prepareStatement(SELECT_PICTURE);
            ResultSet rs =  ps.executeQuery();
            while (rs.next()) {
                //save blob as an image
                FileOutputStream fos = new FileOutputStream("C:\\foto_modified.jpg");
                //String id = rs.getString(1);
                //String name = rs.getString(2);
                InputStream is  = rs.getBinaryStream(3);
                byte[] buf = new byte[3000];
                int read = 0;
                while ((read = is.read(buf)) > 0) {
                    fos.write(buf, 0, read);
                }
                fos.close();
                is.close();
            }

        } finally {
            ps.close();
            fis.close();
        }
    }
    
    
    public static byte[] getBytesFromFile(File file) throws IOException {
            InputStream is = new FileInputStream(file);
            long length = file.length();
    
            byte[] bytes = new byte[(int) length];
    
            int offset = 0;
            int numRead = 0;
            while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
                offset += numRead;
            }
    
            if (offset < bytes.length) {
                throw new IOException("Não foi possível ler o arquivo: " + file.getName());
            }
    
            is.close();
            return bytes;
    }
}

[]´s

Daniel

gregowbr

Vlw mesmo cara, funcionouu finalmente!

mas e agora como eu faço para adicionar esse binário no ImageIcon sem ter que criar a imagem no HD e localizar a imagem.

Quero de uma forma simultânea, que ele crie a imagem a partir dos Bytes alí na tela mesmo.

Vlw !

yorgan

Quando você recuperar os bytes você cria um novo ImageIcon assim:

new ImageIcon(bytes).getImage();

que no seu código fica:

package testes;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class BlobSample {
    public static void main(String[] args) throws Exception, IOException, SQLException {
      
        Connection conn = Conexao.pegarConexao();
        String INSERT_PICTURE = "insert into pictures(id, name, photo) values (?, ?, ?)";

        FileInputStream fis = null;
        PreparedStatement ps = null;
        try {
            //save image as blob
            conn.setAutoCommit(false);
            File file = new File("C:\\foto_original.jpg");
            fis = new FileInputStream(file);
            ps = conn.prepareStatement(INSERT_PICTURE);
            ps.setString(1, "2");
            ps.setString(2, "foto_original");
            ps.setBytes(3, getBytesFromFile());  //Eu utilizo o método setBytes();
            ps.executeUpdate();
            conn.commit();

            //read back
            String SELECT_PICTURE = "select id, name, photo from pictures";
            ps = conn.prepareStatement(SELECT_PICTURE);
            ResultSet rs =  ps.executeQuery();
            while (rs.next()) {
                ImageIcon imagem = new ImageIcon(rs.getBytes(3)); //Utilizando o getBytes();
                imagem.getImage(); //Retorna um Image
            }

        } finally {
            ps.close();
            fis.close();
        }
    }
    
    
    public static byte[] getBytesFromFile(File file) throws IOException {
            InputStream is = new FileInputStream(file);
            long length = file.length();
    
            byte[] bytes = new byte[(int) length];
    
            int offset = 0;
            int numRead = 0;
            while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
                offset += numRead;
            }
    
            if (offset < bytes.length) {
                throw new IOException("Não foi possível ler o arquivo: " + file.getName());
            }
    
            is.close();
            return bytes;
    }
}

Flww

gregowbr

Cara eu te amooo!!

Vlw mesmo brother. Ajudou bastante, agora chega de ficar armazenando imagenszinhas em Pastas, agora vai ser tudo no banco de dados. ;D

vlww aê!

Criado 24 de novembro de 2009
Ultima resposta 25 de nov. de 2009
Respostas 4
Participantes 2