Как сохранить и прочитать картинку, а также произвольный файл?

mg&sv
Дата: 13.08.2003 13:34:18
Как сохранить и прочитать картинку, а также произвольный файл?
Не понимаю, как обстоят дела ни на сервере, ни на клиенте.
Помогите господа!

Где BLOB поля и можно ли использовать typea?
CREATE TYPE bigobj (INPUT = lo_filein, OUTPUT = lo_fileout,
INTERNALLENGTH = VARIABLE);
Не работает по причине неизвестной функции lo_filein

P.S. Если можно подробно (долго иска прежде).
Konrad
Дата: 14.08.2003 08:20:09

CREATE TABLE blob_object
(
blob_id SERIAL,
blob_obj OID,
blob_filename VARCHAR(255)
);

OID предпочтительнее TYPEA, на этом форуме об этом уже говорилось.

Вставить файл в поле blob_obj можно с помощью функции lo_import:

INSERT INTO blob_object (blob_obj, blob_filename)
VALUES (lo_import('/dir/file.doc'), 'file.doc');


Однако, судя по всему, в консоли ты работать с большими объектами не будешь.
В среде web можно сделать, скажем, на РНР, скрипт, который позволяет произвести UPLOAD файла на сервер и закачку его в таблицу:

index.php:

<?php
@$conn=pg_connect("");

//Обработка загруженного на сервер файла:
if (isset($sub_file) && $sub_file!="
")
{
echo "
Размер:$userfile_size<br>
На клиенте файл называется:$userfile_name<br>
На сервере временно хранится под именем:$userfile<br>";

if (@copy($userfile, "
/dir/$userfile_name"))
//Убедись, что директория /dir/ доступна для записи (chmod 777)
{
exec(escapeshellcmd("
chmod 644 $userfile_name")); //Для чтения
echo ("
Файл удачно загружен<br>");
}
else
{
echo ("
Ошибка копирования файла<br>");
}
@unlink($userfile);
//Помещение файла в таблицу
$file_handle=fopen("
$userfile_name", "rb"); //Открываем курсор файла, который мы только что закачали на сервер для бинарного чтения (rb)
$file_content = fread($file_handle, filesize($userfile_name)); //Читаем файл в переменную
fclose($file_handle); //Закрываем курсор
pg_exec ($conn, "
BEGIN;"); //Работа с lo требует транзакции
$oid = pg_locreate ($conn); //Создаем большой объект
$handle = pg_loopen ($conn, $oid, "
wb"); //Открываем его для записи (на всякий случай к флагу w добавляем b для бинарников)
pg_lowrite ($handle, $file_content); //Записываем в объект содержимое файла
if (@pg_exec($conn, "
INSERT INTO blob_object (blob_obj, blob_filename) VALUES ($oid, '$userfile_name');"))
{
echo "
Данные в таблице успешно сохранены";
//Сохраняем в таблице информацию об объекте и файле
}
else
{
echo "
Ошибка сохранения данных!";
pg_exec ($conn, "
ROLLBACK;"); //Откатываем транзакцию
}
pg_loclose ($handle); //Закрываем курсор большого объекта
pg_exec ($conn, "
COMMIT;"); //Успешно завершаем транзакцию
@unlink($userfile_name);
$sub_file="
";
}


//Удаление файла из таблицы и непосредственно большого объекта (lo) из базы:
if (isset($del) && $del!="
")
{
$qu=pg_exec($conn, "
SELECT * FROM blob_object ORDER BY blob_id;");
$nr=pg_numrows($qu);
for ($i=0; $i<$nr; $i++)
{
$file=pg_result($qu, $i, 0);
if ($ch[$file]=="
on")
{
$qu_obj=pg_exec($conn, "
SELECT blob_obj::INTEGER FROM blob_object WHERE b_id=$file;");
$obj=pg_result($qu_obj, 0,0);
pg_exec($conn, "
SELECT lo_unlink($obj);"); //Удаляем большой объект из файловой системы
pg_exec($conn, "
DELETE FROM blob WHERE b_id=$file;"); //Удаляем запись о большом объекте из таблицы
}
}
$del="
";
}
?>

//Вывод списка доступных файлов в таблице на экран в виде ссылок:
<br><br>
<form action="
<?php echo $php_self?>" method=post>
Имеющиеся blob-Файлы:
<table border=1>
<?php
$qu=pg_exec($conn, "
SELECT * FROM blob_object ORDER BY blob_id;");
$nr=pg_numrows($qu);
for ($i=0; $i<$nr; $i++)
{
$file=pg_result($qu, $i, 0);
echo "
<tr>";
echo "
<td>".pg_result($qu, $i, 0)."</td>";
echo "
<td>".pg_result($qu, $i, 1)."</td>";
echo "
<td><a href=\"download.php?file=$file\">".pg_result($qu, $i, 2)."</a></td>";
echo "
<td><input type=checkbox name=ch[$file]></td>";
echo "
</tr>";
}
?>
<tr><td colspan=4><input type="
submit" name=del value="Удалить выбранные"></td></tr>
</table>
</form>

//Форма для закачки файла с компьютера клиента на сервер:
<br>
<form action="
<?php echo $php_self?>" method=post ENCTYPE="multipart/form-data">
Добавить файл:
<INPUT TYPE="
hidden" name="MAX_FILE_SIZE" value="1048576"><!--1MB-->

<input type=file name=userfile>
<br><input type=submit name="
sub_file" value="Добавить"> (Максимальный размер файла - 1 МБ)
</form>


Скачать файл, находящийся в таблице.
download.php:


<?php
@$conn=pg_connect("");
pg_exec ($conn, "
BEGIN;"); //Открываем транзакцию

$qu=pg_exec($conn, "
SELECT blob_obj, blob_filename FROM blob_object WHERE b_id=$file;");
$handle = pg_loopen ($conn, pg_result($qu,0,0), "
r"); //Открываем большой объект для чтения
$filename=pg_result($qu,0,1); //Читаем имя файла

//Посылаем заголовок, сообщающий браузеру, что файл - бинарник, и его нужно скачать:
header("
Content-Disposition: attachment; filename=$filename");
header("
Content-type: application/octet-stream");

pg_loreadall($handle); //Читаем весь большой объект
pg_loclose ($handle); //Закрываем курсор
pg_exec ($conn, "
COMMIT"); //Успешно закрываем транзакцию
?>


Еще можно работать с большими объектами где-нибудь в visual-среде (например, в Delphi при помощи компонент Zeos). Но, честно говоря, корректно обработать lo в Delphi у меня не получилось :( Если вдруг раскопаешь принцип работы с большими объектами посредством этих компонентов - буду признателен.
mg&sv
Дата: 14.08.2003 10:01:45
Как так получилось, не знаю, но я не указал среду разработки C++ Builder 6.
Все модификации предполагается выполнять из клиента и не хотелось бы использовать Zeos (по всей вероятности это геморрой).