Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Загрузка больших файлов в БД.


Автор: powerOn 6.5.2006, 15:08
Всем привет.
Пытаюсь загрузить большой файл (более 20 мб) в БД MySql
вот кусок кода:
Код

private void addNewFile(String name, File f) {
        try {
            FileInputStream fis = new FileInputStream(f);
            
            PreparedStatement stmt = connection.prepareStatement("Select * from `files`",
                    ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
            stmt.execute();
            ResultSet rs = stmt.getResultSet();
            
            rs.moveToInsertRow();
            Blob blob = rs.getBlob("data");
            OutputStream os = blob.setBinaryStream(1);
            
            System.out.println("start load file: " + name);
            while (fis.available() > 0) {
                

                int block_size = 1000000;
                if (fis.available() < 1000000) {
                    block_size = fis.available();
                }
                System.out.println("try read bytes: " + block_size);
                byte b [ ] = new byte[block_size];
                
                fis.read(b);
                System.out.println("read ok, writing");
                os.write(b);
                os.flush();
                System.out.println("writing complite. check for next block...");
                System.gc(); 
            }
            System.out.println("loading file " + name + " complite.");
            os.close();
            fis.close();
            rs.updateBlob("data", blob);
            rs.updateString("name", name);
            rs.insertRow();
            stmt.close();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

 

и вроде все как надо, файлы поменьше загружаются без проблем, но когда дело доходит до больших файлов, то JVM не хватает памяти. Вылетает: 
Цитата

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space


Впринципе, данных действительно не мало, но как то странно что больше (примерно) 20 метров уже загрузить нельзя.... чувствую, что ошибка-то десткая, но найти не получается...  smile 
подскажите, как правильно большие данные загрузить в БД? 

Автор: tux 6.5.2006, 17:46
Я тоже не вижу никаких проблем. Единственное предположение - реализация JDBC-драйвера такова, что накапливает в памяти все содержимое BLOB прежде чем слить в базу данных (вариант - MySQL по-другому не умеет). Точнее пока сказать не могу, файлы большого объема аплоудить не приходилось. 

Автор: Bulat 6.5.2006, 19:04
А тебе обязательно загружать именно сами файлы в базу? Возможно легче будеть лишь держать в БД ссылки на них?..... 

Автор: powerOn 6.5.2006, 19:50
Цитата

А тебе обязательно загружать именно сами файлы в базу? Возможно легче будеть лишь держать в БД ссылки на них?.....  


Да, обязательно файл в базу нужно загрузить. Из соображений безопасности и целосности данных. Если хранить файлы отдельно, а в базе ссылки, нет ни какой гарантии что файлы не попортят или вообще не сотрут. БД обеспечит бэкап и целосность данных, которые весьма важны и  имеют приличный размер...

 

Автор: powerOn 7.5.2006, 13:11
Ура!!! Разобрался!  smile 

вот как надо большие данные загружать:

Код

private void addNewFile(String name, File f) {
        try {
            FileInputStream fis = new FileInputStream(f);
            
            PreparedStatement stmt = connection.prepareStatement("Insert Into `files` ( `name`, `data` ) values (?,?);",
                    ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
            
            stmt.setString(1, name);
            stmt.setBinaryStream(2, fis, fis.available() );
            
            stmt.executeUpdate();
            stmt.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

 smile 
   

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)