LINUX.ORG.RU

Проблема сохранением фалов из Qt в Postgres


0

2

Имеется СУБД PostgresSQL, в ней таблица с полем bytea, в которое необходимо сохранять PDF-файлы. Делаю это из Qt так:

    QFile file("file.pdf");
    file.open(QIODevice::ReadOnly);
    QByteArray ba = file.readAll();
    m_query->prepare("insert into t_documents (value) values (?)");
    QVariant v;
    v = ba;
    m_query->bindValue(0,v,QSql::In|QSql::Binary);
    m_query->exec();

а считываю

    m_query->exec("select value from t_documents where id=5");
    m_query->next();
    QVariant v1 = m_query->value(1);
    QByteArray ba1 = v1.toByteArray();
    QFile file1("file1.pdf");
    file1.open(QIODevice::WriteOnly);
    file1.write(ba1);
    file1.close();

Считанные файлы не открываются. Попробывал сохранить простой текстовый файл с содержимым 1234567890, а получил x3031323334353637383930. Подозреваю, что-то с кодировкой, возможно надо base64 влепить?


ну в общем, ты сохранил файл аки текст.

31323334353637383930 = это и есть 1234567890, hex коды ascii.

привет тебе от жопоруких авторов qt, ты еще на потребление памяти и проца посмотри когда большие файлы будешь кидать

ckotinko ☆☆☆
()
Последнее исправление: ckotinko (всего исправлений: 1)

Подозреваю, что-то с кодировкой

Нет.

возможно надо base64 влепить

Рекомендую, это правильная штука.

erfea ★★★★★
()
Ответ на: комментарий от erfea

Рекомендую, это правильная штука.

Хранить забейзенные данные в блобе? То есть проигрываем и по объему и по скорости, какая прэлесть.

anonymous
()
Ответ на: комментарий от anonymous

Хранить забейзенные данные в блобе?

Где я сказал хранить в блобе?

То есть проигрываем и по объему и по скорости, какая прэлесть.

Хранить файлы в базе, какая «прэлесть».

erfea ★★★★★
()
Ответ на: комментарий от erfea

Где я сказал хранить в блобе?

TEXT тоже не слаще. Один хрен, ты предлагаешь какой-то стремный костыль, а не решение.

Хранить файлы в базе, какая «прэлесть».

Уж лучше так, чем диры с over 100k файлов.

anonymous
()
Ответ на: комментарий от anonymous

TEXT тоже не слаще. Один хрен, ты предлагаешь какой-то стремный костыль, а не решение.

Зависит от масштабов использования сабжа...

Уж лучше так, чем диры с over 100k файлов.

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

erfea ★★★★★
()

а если напрямую клиентскую библиотеку постгреса дёргать, а не через Qt?

Harald ★★★★★
()
Ответ на: комментарий от erfea

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

Откуда взялась файлопомойка? Задачи БД и ФС пересекаются так что может быть тысяча причин использовать БД.

anonymous
()
Ответ на: комментарий от anonymous

Откуда взялась файлопомойка?

Откуда взялась БД? Анонимус, такой анонимус.

Задачи БД и ФС пересекаются

Они всё-же несколько разные... школота то не вкурсе, но это так.

так что может быть тысяча причин использовать БД.

Претендуешь на погоны капитана?

erfea ★★★★★
()
Ответ на: комментарий от erfea

Откуда взялась БД?

Из сабжа, мой дорогой любитель советовать выкопать колодец, из сабжа.

Они всё-же несколько разные...

Б-г-г. ФС это такая недобд с хреновой атомарностью и зародышем индекса.

Только школота может категорично воспринять задачу хранения бинарных данных.

anonymous
()
Ответ на: комментарий от anonymous

Из сабжа, мой дорогой любитель советовать выкопать колодец, из сабжа.

И ФС из сабжа мой дорогой анонимус, из сабжа.

Б-г-г. ФС это такая недобд с хреновой атомарностью и зародышем индекса.

ФС это ФС. Остальное твоим влажные фантазии.

Только школота может категорично воспринять задачу хранения бинарных данных.

Только школота будет считать идеальным хранилищем файлов бинарное поле в БД. Всё зависит от задачи. Если требуется прилеплять не большую PDFку к какой-то сущности в БД. Если она не большого размера. То, это может быть уместно. Но при таких условиях и base64 строка не плохой вариант (и имеет ряд своих преимуществ). А если тебе таки нужна файлопомойка, лучше использовать средства для этого предназначенные.

erfea ★★★★★
()

у PostgreSQL простой и прямой API, используйте для записи файла напрямую.
Еще PostgreSQL умеет plperlu, можно использовать для записи файлов в ФС, очень удобно.

Serik
()

Локализуй проблему для начала.
Запиши данные по-своему, а прочитай ручками, через консольного или графического клиента.

dmitryalexeeff
()

У меня вот такое работает в проекте уж третий год, без извращений, перекодировок, «кривого Qt» и прямого использования драйверов постгре:

сохранение

        QByteArray fileContents = file.readAll();

        QSqlQuery query;
        query.prepare("INSERT INTO contractfiles (contractid, file, filename) VALUES (:contractid, :file, :filename)");
        query.bindValue(":contractid", m_contractId);
        query.bindValue(":file", fileContents);
        query.bindValue(":filename", fileName);

        if(!query.exec())
            SqlHelper::handle(query.lastError(), tr("Error saving file into database"));

считывание:

    QSqlQuery query;
    query.prepare("SELECT filename, file FROM contractfiles WHERE id = :id");
    query.bindValue(":id", fileId);

    if(!(query.exec() && query.next()))
        SqlHelper::handle(query.lastError(), tr("Error fetching file from database"));

    QString fileName = QDir::tempPath() + "/" + query.value(0).toString();
    QFile file(fileName);
    if(!file.open(QIODevice::WriteOnly))
    {
        QMessageBox::warning(this, tr("File error"), tr("Can't show file %1").arg(fileName));
        return;
    }
    file.write(query.value(1).toByteArray());


#ifdef Q_WS_WIN
    ShellExecuteW(0, L"open", fileName.toStdWString().c_str(), 0, 0, 0);
#endif

unC0Rr ★★★★★
()

У нас было немного файлов (<10) и мы их хранили в BLOB, всё работало, но библиотеки использовали нативные. Правда у нас всё равно было по 2 подключения к БД на 1 клиента (из-за NOTIFY/LISTEN, которые QT не умел тогда).

saper ★★★★★
()
Ответ на: комментарий от erfea

возможно надо base64 влепить

Рекомендую, это правильная штука.

не очень помагает. Записываю файл с текстом «1234567890». В base64 - «MTIzNDU2Nzg5MA==», но в базе уже «M54497a4e4455324e7a67354d413d3d», а при считывании - «x4d54497a4e4455324e7a67354d413d3d».

kryuch
() автор топика
Ответ на: комментарий от saper

Если поле в таблице text, то все работает почему-то. може нафиг bytea?

kryuch
() автор топика
Ответ на: комментарий от kryuch

Что-то у тебя с конфигом постгреса не то, значит

unC0Rr ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.