none
Скачать файл из базы данных Oracle (тип данных: blob) RRS feed

  • Вопрос

  • Добрый день!

    Есть страница aspx.

    Есть таблица BLOB_FILE в базе данных Oracle. В ней столбец FILE_DATA (тип данных: blob) хранит файлы расширения pdf.

    Создаю ссылки на скачивание файлов.

    При нажатие на ссылку вызываю код:

    protected void Page_Load(object sender, EventArgs e)
            {
                string id = Request.QueryString["id"];
                string extension = Request.QueryString["extension"];
    
                using (OracleConnection oraConn = new OracleConnection(WebConfigurationManager.ConnectionStrings["OracleConnectionOSD"].ConnectionString))
                {
                    using (OracleCommand oraComm = new OracleCommand("SELECT file_data FROM blob_file WHERE id = " + id, oraConn))
                    {
                        try
                        {
                            oraConn.Open();
    
                            using (OracleDataReader reader = oraComm.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    byte[] byteArray = (Byte[])reader["file_data"];
                                    Response.Clear();
                                    Response.ContentType = "application/pdf";
                                    Response.AddHeader("content-disposition", "attachment; filename=title." + extension);
                                    Response.BinaryWrite(byteArray);
                                    System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest(); //вместо Response.End();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
    
                        }
                        finally
                        {
                            oraConn.Close();
                        }
                    }
                }
            }

    Скачивание происходит. Но при открытии получаю ошибку: "возникла проблема с форматом файла".

    Буду благодарен за любую помощь.

Ответы

Все ответы

  • Хотел добавить следующее. Файл в базу записан корректно. Есть другой интерфейс, где его можно скачать. Исходников к другому интерфейсу нет. Т.е. ошибка на формировании файла из битов.
  • Подозреваю, что вся магия тут: byte[] byteArray = (Byte[])reader["file_data"]; Т.е. у вас уже массив содержит не те данные при явном приведении.

    Посмотрите в MSDN как читать двоичные данные правильно.


    Сделаем содержимое сообщества лучше, вместе!

    Модератор
  • Спасибо за ссылку. Я уже читал эту статью.

    К своему примеру не получается применить.

    Если я буду использовать пример по вашей ссылке, то натыкаюсь на:

    1. Внутренний цикл while отрабатывает очень долго (1мин при размере файла 3 Мб).

    Пробовал менять размер переменной bufferSize на 1000 и 10000, время уменьшается. Но так как я не очень понимаю что там происходит в цикле с байтами, то не знаю, стоит ли менять значение.

    2. Проблема передачи FileStream в Response. FileStream не поддерживает метод Read в режиме FileMode.OpenOrCreate (или по какой-то другой причине).

    Мне кажется как-то по-другому все это надо провернуть. Пока ищу как.



    • Изменено ilya83 13 мая 2015 г. 12:50
  • Используя Вашу ссылку, вот к чему я пришел:

    protected void Page_Load(object sender, EventArgs e)
            {
                string id = Request.QueryString["id"];
                string extension = Request.QueryString["extension"];
    
                using (OracleConnection oraConn = new OracleConnection(WebConfigurationManager.ConnectionStrings["OracleConnectionOSD"].ConnectionString))
                {
                    using (OracleCommand oraComm = new OracleCommand("SELECT file_data FROM blob_file WHERE id = " + id, oraConn))
                    {
                        try
                        {
                            oraConn.Open();
    
                            FileStream stream;                              //универсальное представление последовательности байтов в файле
                            BinaryWriter writer;                            //записывает простые типы данных в поток как двоичные значения
                            int bufferSize = 100;                         //размер буфера для blob
                            byte[] outByte = new byte[bufferSize];
                            long retval;                                    //возвращенные байты из GetBytes
                            long startIndex = 0;
      
                            OracleDataReader reader = oraComm.ExecuteReader(CommandBehavior.SequentialAccess);
                            while (reader.Read())
                            {    
                                stream = new FileStream("logo.pdf", FileMode.OpenOrCreate, FileAccess.Write);           //создадим файл для хранения
                                writer = new BinaryWriter(stream);                                                      //создадим экземпляр BinaryWriter на основании потока
    
                                startIndex = 0;
    
                                // считывает поток байтов из заданного смещения столбца в буфер в виде массива, начиная с заданного смещения буфера
                                retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
                                //0 - Порядковый номер столбца (начиная с нуля)
                                //startIndex - индекс с которого начинается операция считывания
                                //outByte - буфер, в который записывается поток байтов
                                //0 - индекс в outByte, с которого должна начинаться операция записи
                                //bufferSize - максимальная длина для копирования в буфер
    
                                // Continue while there are bytes beyond the size of the buffer.
                                while (retval == bufferSize)
                                {
                                    //выполняет запись массива байтов в базовый поток
                                    writer.Write(outByte);
                                    //очищает все буферы текущего модуля записи и вызывает немедленную запись всех буферизованных данных в FileStream
                                    writer.Flush();
    
                                    //сдвигаем начальный индекс
                                    startIndex += bufferSize;
                                    retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
                                }
    
                                // Write the remaining buffer.
                                writer.Write(outByte, 0, (int)retval - 1);
                                //outByte - массив с данными
                                //0 - начальная позиция для записи
                                //(int)retval - 1 - кол-во байтов для записи
    
                                writer.Flush();
    
                                writer.Close();
                                stream.Close();
                            }
    
                            reader.Close();                        
                        }
                        catch (Exception ex)
                        {
    
                        }
                        finally
                        {
                            oraConn.Close();
                        }
                    }
                }
            }

    Сейчас я не рассматриваю идею передачи файла.

    При отработке, данный код создает файл logo.pdf в папке C:\Windows\System32\inetsrv

    Файл не открывается, ошибка "возникла проблема с форматом файла". И еще, этот файл на 400 кБ меньше, чем тот, который я скачиваю с другого интерфейса.

  • Уважаемые разработчики. Нужен совет.

    1. Есть скаченный файл pdf. Нажимаю св-ва -> размер 3 638 762 байт.

    2. Когда я его считываю с базы

    OracleDataReader reader = oraComm.ExecuteReader(CommandBehavior.SequentialAccess);
    while (reader.Read())
    {  
    
    }

    в дебаге вижу следующее

    reader[0] = {byte[3 103 801]}

    Такое может быть?

  • Тема закрыта. Файл лежал в архиве оказывается.
    • Помечено в качестве ответа ilya83 14 мая 2015 г. 8:20