none
Gravar arquivo pdf no Banco de dados RRS feed

  • Pergunta

  • Bom dia pessoal

    Eu e minhas perguntas simples novamente :)

    Então vamos lá

    Eu tenho dois metodos que fazem o seguinte caso.

    O primeiro metodo (ConverterArquivo_to_binario) faz o procedimento correto que converte para byte

     public class Arquivo_to_binario_to_arquivo
        {
            public byte[] ConverterArquivo_to_binario(string caminhoArquivo)
            {

                StreamReader oStreamReader = new StreamReader(caminhoArquivo);

                byte[] buffer = new byte[oStreamReader.BaseStream.Length];

                oStreamReader.BaseStream.Read(buffer, 0, buffer.Length);

                oStreamReader.Close();
                oStreamReader.Dispose();

                return buffer;
            }

    O segundo faz o inverso e funciona normalmente.

            public string ConverterBinario_to_arquivo(string nomearquivo,Arquivo objarquivo)
            {
                string local = @"C:\ARQUIVO\";
                StreamWriter oStreamWriter = new StreamWriter(local + nomearquivo);

                oStreamWriter.BaseStream.Write(objarquivo.Arquivobin, 0, objarquivo.Arquivobin.Length);

                oStreamWriter.Close();
                oStreamWriter.Dispose();
                string arquivosalvo = local + objarquivo.Nomearquivo;
                return arquivosalvo;


            }

        }

    Metodo Incluir funciona

    String stringsql;
                stringsql = "INSERT INTO arquivos(Nomearquivo,Arquivobin,Login,Ano,Proventos,Empresa,Mes )" +
                            "Values('" + objarquivo.Nomearquivo + "','" + objarquivo.Arquivobin + "','" + objarquivo.Login + "'," + objarquivo.Ano + ",'" + objarquivo.Proventos + "','" + objarquivo.Empresa + "','" + objarquivo.Mes + "');";

                ExecutarComando(stringsql);

    Metodo Obter funciona

     String stringSql = string.Empty;
                MySqlDataReader resultadoConsulta;

                stringSql = "SELECT * FROM arquivos where nomearquivo='"+ nomearquivo +"';";
                
                resultadoConsulta =  ExecutarConsulta(stringSql);
                byte[] buffer = null;
                var arquivo = new Arquivo();
                if (resultadoConsulta.Read())
                {
                    
                    arquivo.Id = Int32.Parse(resultadoConsulta["Id"].ToString());
                    arquivo.Nomearquivo = resultadoConsulta["Nomearquivo"].ToString();
                    arquivo.Login = resultadoConsulta["Login"].ToString();
                    arquivo.Ano = Int32.Parse(resultadoConsulta["Ano"].ToString());
                    arquivo.Proventos = resultadoConsulta["Proventos"].ToString();
                    arquivo.Empresa = resultadoConsulta["Empresa"].ToString();
                    arquivo.Mes = resultadoConsulta["Mes"].ToString();
                    buffer = (byte[])resultadoConsulta["arquivobin"];
                    arquivo.Arquivobin = buffer;
                                    
                }
                resultadoConsulta.Close();
                return arquivo;

    No Mysql o arquivobin foi definido como tipo LONGBLOB

    O meu problema é quando eu recupero esse dado binario do banco de dados mysql ele me retorna um arquivo bem menor e corrompido. Aonde eu estou errando nisso. Alguem pode me ajudar no assunto?

    Já fiz o teste não gravando no banco de dados e funciona corretamente.

    Att

    Fabricio Vale


    Fabricio

    terça-feira, 2 de fevereiro de 2016 12:52

Respostas

  • Faz insert com parametros.

    Teu insert nao faz sentido. Use parametros.


    A flower cannot blossom without sunshine, and man cannot live without love.


    • Editado Marcos SJ terça-feira, 2 de fevereiro de 2016 14:53 Edição
    • Sugerido como Resposta Fulvio Cezar Canducci Dias terça-feira, 2 de fevereiro de 2016 19:34
    • Marcado como Resposta Marcos SJ quarta-feira, 3 de fevereiro de 2016 11:35
    terça-feira, 2 de fevereiro de 2016 14:43
    Moderador
  • Vamos dizer que você tenha uma classe que represente sua Tabela no banco:

    public class Arquivo
    {
    	public Arquivo()
    	{
    
    	}
    	public Arquivo(string nome, byte[] data)
    	{
    		Nome = nome;
    		Data = data;
    	}
    	public Arquivo(int id, string nome, byte[] data)
    	{
    		Id = id;
    		Nome = nome;
    		Data = data;
    	}
    	public int Id { get; set; }
    	public string Nome { get; set; }
    	public byte[] Data { get; set; }
    
    }

    E precisa gravar ela no seu banco de dados aonde Data é o arquivo transformado em Array de Bytes! Eu percebi que você está lendo um arquivo em disco então fica fácil assim!

    Arquivo arquivo = new Arquivo();
    
    arquivo.Data = System.IO.File.ReadAllBytes("pdf/1.pdf");
    arquivo.Nome = "Exemplo 1";

    Aonde "pdf/1.pdf" é o caminho do seu arquivo gravado no disco ... (simplesmente utilize a classe pronta do .NET (System.IO.File.ReadAllBytes).

    Para gravar isso na tabela tem que se passar via Parameter os dados !

    public Arquivo Add(Arquivo model)
    {
    	using (SqlCommand command = _connection.Get.CreateCommand())
    	{
    		command.CommandText = "INSERT INTO Arquivos(Nome, Data) VALUES(@Nome,@Data); SELECT SCOPE_IDENTITY();";
    		command.Parameters.Add("@Nome", SqlDbType.NVarChar, 50).Value = model.Nome;
    		command.Parameters.Add("@Data", SqlDbType.VarBinary).Value = model.Data;                
    		model.Id = int.Parse(command.ExecuteScalar().ToString());
    	}
    	return model;
    }

    Observer no código, é assim que é o modo correto ...

    Recuperando um item da lista:

    public Arquivo Find(params object[] keys)
    {
    	Arquivo arquivo = null;
    	using (SqlCommand command = _connection.Get.CreateCommand())
    	{
    		command.CommandText = "SELECT Id, Nome, Data FROM Arquivos WHERE Id=@Id";
    		command.Parameters.Add("@Id", SqlDbType.Int).Value = keys[0];
    		using (SqlDataReader reader = command.ExecuteReader())
    		{
    			if (reader.HasRows)
    			{
    				reader.Read();
    				arquivo = new Arquivo(reader.GetInt32(0), reader.GetString(1), (byte[])reader[2]);
    			}
    		}
    	}
    	return arquivo;
    }

    e simples e agora faça

    Arquivo arquivo1 = dalArquivo.Find(1);
    System.IO.File.WriteAllBytes("pdf/" + Guid.NewGuid().ToString() + ".pdf", arquivo1.Data);

    Essa é a forma trivial para gravar e recuperar informações em um modo correto de desenvolvimento com parameter e classes já existente no .NET para conversão de arquivos ...


    Fulvio C

    terça-feira, 2 de fevereiro de 2016 20:33

Todas as Respostas

  • Fabricio, antes de mais nada, 

    é extremamente necessário que vc grave pdfs no teu banco? Já calculaste o consumo de recursos desta operação?

    Att, wsti.

    terça-feira, 2 de fevereiro de 2016 12:58
  • Faz insert com parametros.

    Teu insert nao faz sentido. Use parametros.


    A flower cannot blossom without sunshine, and man cannot live without love.


    • Editado Marcos SJ terça-feira, 2 de fevereiro de 2016 14:53 Edição
    • Sugerido como Resposta Fulvio Cezar Canducci Dias terça-feira, 2 de fevereiro de 2016 19:34
    • Marcado como Resposta Marcos SJ quarta-feira, 3 de fevereiro de 2016 11:35
    terça-feira, 2 de fevereiro de 2016 14:43
    Moderador
  • Os pdf's tem um tamanho que não passa de 30kbytes.

    E como ficaria o insert com parametros?

    e em relação ao Banco de dados que tipo que eu defino(Blob,Varbinary,Longblob)

    Abs

    Att

    Fabricio Vale


    Fabricio

    terça-feira, 2 de fevereiro de 2016 15:14
  • Fiz o seguinte:

    Mysql Campo arquivobin: esta como BLOB

    Fiz uma inserção manualmente pelo Query browser de um arquivo pdf

    Executei o meu metodo obter e funcionou e conseguir salvar o arquivo.pdf e abre normalmente

    Então o meu problema realmente esta no metodo incluir. Como resolve isso?

    Att

    Fabricio Vale


    Fabricio

    terça-feira, 2 de fevereiro de 2016 15:58
  • Kra, o seu problema é parecido com isso, então a solução deve servir: saving-byte-array-to-mysql.

    Agora, além disso, da uma olhada nesse post retrieve-longblob-from-mysql-in-c-sharp para rever o SELECT, porque tem algo estranho nele.

    terça-feira, 2 de fevereiro de 2016 16:39
  • Vamos dizer que você tenha uma classe que represente sua Tabela no banco:

    public class Arquivo
    {
    	public Arquivo()
    	{
    
    	}
    	public Arquivo(string nome, byte[] data)
    	{
    		Nome = nome;
    		Data = data;
    	}
    	public Arquivo(int id, string nome, byte[] data)
    	{
    		Id = id;
    		Nome = nome;
    		Data = data;
    	}
    	public int Id { get; set; }
    	public string Nome { get; set; }
    	public byte[] Data { get; set; }
    
    }

    E precisa gravar ela no seu banco de dados aonde Data é o arquivo transformado em Array de Bytes! Eu percebi que você está lendo um arquivo em disco então fica fácil assim!

    Arquivo arquivo = new Arquivo();
    
    arquivo.Data = System.IO.File.ReadAllBytes("pdf/1.pdf");
    arquivo.Nome = "Exemplo 1";

    Aonde "pdf/1.pdf" é o caminho do seu arquivo gravado no disco ... (simplesmente utilize a classe pronta do .NET (System.IO.File.ReadAllBytes).

    Para gravar isso na tabela tem que se passar via Parameter os dados !

    public Arquivo Add(Arquivo model)
    {
    	using (SqlCommand command = _connection.Get.CreateCommand())
    	{
    		command.CommandText = "INSERT INTO Arquivos(Nome, Data) VALUES(@Nome,@Data); SELECT SCOPE_IDENTITY();";
    		command.Parameters.Add("@Nome", SqlDbType.NVarChar, 50).Value = model.Nome;
    		command.Parameters.Add("@Data", SqlDbType.VarBinary).Value = model.Data;                
    		model.Id = int.Parse(command.ExecuteScalar().ToString());
    	}
    	return model;
    }

    Observer no código, é assim que é o modo correto ...

    Recuperando um item da lista:

    public Arquivo Find(params object[] keys)
    {
    	Arquivo arquivo = null;
    	using (SqlCommand command = _connection.Get.CreateCommand())
    	{
    		command.CommandText = "SELECT Id, Nome, Data FROM Arquivos WHERE Id=@Id";
    		command.Parameters.Add("@Id", SqlDbType.Int).Value = keys[0];
    		using (SqlDataReader reader = command.ExecuteReader())
    		{
    			if (reader.HasRows)
    			{
    				reader.Read();
    				arquivo = new Arquivo(reader.GetInt32(0), reader.GetString(1), (byte[])reader[2]);
    			}
    		}
    	}
    	return arquivo;
    }

    e simples e agora faça

    Arquivo arquivo1 = dalArquivo.Find(1);
    System.IO.File.WriteAllBytes("pdf/" + Guid.NewGuid().ToString() + ".pdf", arquivo1.Data);

    Essa é a forma trivial para gravar e recuperar informações em um modo correto de desenvolvimento com parameter e classes já existente no .NET para conversão de arquivos ...


    Fulvio C

    terça-feira, 2 de fevereiro de 2016 20:33
  • Bom dia Fulvio

    Estou fazendo da seguinte forma simples pra saber por que o comando abaixo em negrito não funciona.

    public void Incluir(Arquivo objarquivo)
        {
            try
            {

                string StringConexao = "Host=meuip" +
                                    "Database=meuBd;" +
                                    "UserName=meuusuario;" +
                                    "Password=senha";

                MySqlConnection Conexao = new MySqlConnection(StringConexao);
                Conexao.Open();

                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = Conexao;
                cmd.CommandText = "INSERT INTO arquivos (Nomearquivo) values (@Arquivobin);SELECT SCOPE_IDENTITY();";
                cmd.CommandType = CommandType.Text;
                
               

                cmd.Parameters.Add("@Arquivobin",MySqlDbType.VarBinary).Value=objarquivo.Arquivobin;
                
              //Até aqui funciona normalmente

                cmd.ExecuteNonQuery(); //Esse comando não funciona. Por que?
                Conexao.Close();

          }
            catch (Exception ex)
            {

                throw new Exception("Método Incluir da Classe ArquivoDAO", ex);
            }
    }

    Abs

    Fico no aguardo

    Att

    Fabricio Vale


    Fabricio

    quarta-feira, 3 de fevereiro de 2016 11:23
  • Bom dia Fulvio

    Estou fazendo da seguinte forma simples pra saber por que o comando abaixo em negrito não funciona.

    public void Incluir(Arquivo objarquivo)
        {
            try
            {

                string StringConexao = "Host=meuip" +
                                    "Database=meuBd;" +
                                    "UserName=meuusuario;" +
                                    "Password=senha";

                MySqlConnection Conexao = new MySqlConnection(StringConexao);
                Conexao.Open();

                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = Conexao;
                cmd.CommandText = "INSERT INTO arquivos (Nomearquivo) values (@Arquivobin);SELECT SCOPE_IDENTITY();";
                cmd.CommandType = CommandType.Text;
                
               

                cmd.Parameters.Add("@Arquivobin",MySqlDbType.VarBinary).Value=objarquivo.Arquivobin;
                
              //Até aqui funciona normalmente

                cmd.ExecuteNonQuery(); //Esse comando não funciona. Por que?
                Conexao.Close();

          }
            catch (Exception ex)
            {

                throw new Exception("Método Incluir da Classe ArquivoDAO", ex);
            }
    }

    Abs

    Fico no aguardo

    Att

    Fabricio Vale


    Fabricio

    Retire da SQL SELECT SCOPE_IDENTITY();

    Isso não funciona em MySQL! é só isso


    Fulvio C

    quarta-feira, 3 de fevereiro de 2016 13:51
  • Fulvio boa tarde!

    Funcionou. Muito obrigado, vlw mesmo. Deus lhe ajude.

    O codigo então ficou da seguinte forma:

    Tabela:

    CREATE TABLE  `painelcontrol`.`arquivos` (
      `Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `arquivobin` blob NOT NULL,
      PRIMARY KEY (`Id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=latin1;

    Codigo C#:

     string StringConexao = "Host=meuip;" +
                                    "Database=painelcontrol;" +
                                    "UserName=root;" +
                                    "Password=senha;";

                MySqlConnection Conexao = new MySqlConnection(StringConexao);
                Conexao.Open();

                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = Conexao;
                cmd.CommandText = "INSERT INTO arquivos (Arquivobin) values (@Arquivobin);";
                cmd.CommandType = CommandType.Text;
                         
                cmd.Parameters.Add("@Arquivobin",MySqlDbType.Blob).Value=objarquivo.Arquivobin;
                
                cmd.ExecuteNonQuery();
                Conexao.Close();

    Pessoal se não fosse vcs hoje eu não seria o que sou na empresa.

    Não sei o que dizer mais vocês são bons no que fazem.

    Abs e um feliz carnaval pra todos

    Att

    Fabricio Vale


    Fabricio

    quarta-feira, 3 de fevereiro de 2016 15:28
  • Boa noite Fabrício, tudo bem ?

    Estou com dificuldade em fazer o que você fez no seu sistema. Será que você poderia me ajudar ?


    Philipe Khemil Said

    sexta-feira, 10 de junho de 2016 23:30