Как сохранить изображение в Java в несколько BLOB-объектов?

Как я описал в заголовке, я несколько раз пытался получить доступ к файлу изображения, используя InputStream, а затем сохранить его в базе данных типа blob, но результат для второго, третьего и так далее нулевой. Вот фрагмент кода:

File image1 = new File("src/template1.png").getAbsoluteFile();
File image2 = new File("src/template2.png").getAbsoluteFile();
InputStream in1 = new FileInputStream(image1);
InputStream in2 = new FileInputStream(image2);
long length1 = image1.length();
long length2 = image2.length();
pstmt.setString(1, jTextField18.getText().toUpperCase());
pstmt.setBlob( 2, in1, length1 );
pstmt.setBlob( 3, in1, length1 );
pstmt.setBlob( 4, in1, length1 );
pstmt.setBlob( 5, in1, length1 );
pstmt.setBlob( 6, in1, length1 );
pstmt.setBlob( 7, in2, length2 );
Pstmt.setBlob( 8, in2, length2 );

тогда результат:

YR/21
[BLOB - 5.6 KiB]
[BLOB - 0 B]
[BLOB - 0 B]
[BLOB - 0 B]
[BLOB - 0 B]
[BLOB - 5.5 KiB]
[BLOB - 0 B]

Я попытался использовать новый InputStream, подобный этому коду, и произошла другая ошибка. Пишет: Слишком большой размер строки (>8126). Может помочь изменение некоторых столбцов на TEXT или BLOB или использование ROW_FORMAT=DINAMIC или ROW_FORMAT=COMPRESSED. В текущем формате строки префикс BLOB размером 768 байт хранится в строке.

pstmt.setBlob( 2, in1, length1 );
image1 = new File("src/template1.png").getAbsoluteFile();
in1 = new FileInputStream(image1);
pstmt.setBlob( 3, in1, length1 );
image1 = new File("src/template1.png").getAbsoluteFile();
in1 = new FileInputStream(image1);
pstmt.setBlob( 4, in1, length1 );

Я думаю, что проблема решена и превращается в другую проблему. Спасибо за ответ


person cappucino    schedule 14.04.2014    source источник
comment
@kdgregory: это должен быть ответ   -  person JB Nizet    schedule 14.04.2014


Ответы (2)


Первый вызов потребляет поток, а последующие вызовы не получают данных. Вам нужен отдельный InputStream для каждого вызова.

person jtahlborn    schedule 14.04.2014
comment
я пытался использовать другой поток ввода, но он по-прежнему не может прочитать тот же файл, результат по-прежнему [BLOB - 0 B] - person cappucino; 14.04.2014
comment
извините, я даю вводящий в заблуждение ответ, я пытался использовать другой поток ввода, а затем произошла какая-то ошибка. пишет: Слишком большой размер строки(›8126). Может помочь изменение некоторых столбцов на TEXT или BLOB или использование ROW_FORMAT=DINAMIC или ROW_FORMAT=COMPRESSED. В текущем формате строки префикс BLOB размером 768 байт хранится в строке @jtahlborn. - person cappucino; 15.04.2014

«Есть ли способ сохранить изображение в несколько BLOB-объектов?»

Да, но ваш код будет работать только для небольших изображений. Вместо этого создайте родительскую ссылку на изображение и дочернюю ссылку на фактическое изображение, которое будет содержать большие двоичные объекты. Сделайте детей маленькими и сохраните только часть изображения для каждого из них.

Это поможет вам управлять пространством и будет проще создавать резервные копии.

Справку о том, как читать файл по частям, см. здесь: http://www.javapractices.com/topic/TopicAction.do?Id=245

Сохраните фрагмент изображения в базе данных, используя цикл while, который считывает файл.

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

Если вы используете MySQL, есть руководство по чтению и записи изображений: http://zetcode.com/db/mysqljava/

Веселиться.

person Alexandre Santos    schedule 14.04.2014
comment
Я думаю, вы неправильно поняли мой вопрос, извините за мою двусмысленность, я пытаюсь сказать, что хочу сохранить изображение в нескольких BLOB-объектах, 1 BLOB-объект 1 изображение, например a.jpg в BLOB-объекте 1, a.jpg в BLOB-объекте 2, и так далее, одна и та же картинка в разных блобах - person cappucino; 14.04.2014
comment
Хорошо, в этом случае вам нужно закрыть поток и снова открыть его... или использовать неблокирующий ввод-вывод, но я не думаю, что подготовленный оператор может работать с неблокирующим. ... В отдельной теме ваш код мог бы работать, если бы вы сохранили изображение только в одном BLOB-объекте и сделали ссылки на первый. Это сэкономит вам много места в базе данных. Но я не пытаюсь изменить ваши требования. Благодарю за разъяснение. - person Alexandre Santos; 14.04.2014