Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Hellrider от Декабрь 27, 2012, 14:06



Название: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 14:06
Можно ли реализовать во время исполнения приложения, извлечение файла из ресурсов qrc? Есть wav файл, который из ресурсов по средством QSound не проигрывается, но таскать вместе
с приложением звуковой файл не вариант.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Пантер от Декабрь 27, 2012, 14:07
Как пытаешься проиграть?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 14:12
Код:
QSound::play("://ir_inter.wav");


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 27, 2012, 14:15
QSound не проигрывает файл из ресурсов. Уже куча тем была.
Да, можно реализовать.
Копировать вроде можно.
И проигрывать уже из темповой папки.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 14:18
QSound не проигрывает файл из ресурсов. Уже куча тем была.
Да, можно реализовать.
Копировать вроде можно.
И проигрывать уже из темповой папки.

Хотелось бы узнать, как именно это реализовать.  ::)


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 27, 2012, 14:24
Могу ошибаться насчёт копирования.
псевдокод
Код:
QString temp; // не помню синтаксиса, но получаем темповую папку
QFile file("://resource/temp.wav");
if (file.copy(temp + "in_inter.wav"))
{
   qDebug() << "true";
   QSound::play(temp + "in_inter.wav");
}
else
   qDebug() << QString("error copy sound. Path %1!").arg(temp + "in_inter.wav");


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 14:42
Могу ошибаться насчёт копирования.
псевдокод
Код:
QString temp; // не помню синтаксиса, но получаем темповую папку
QFile file("://resource/temp.wav");
if (file.copy(temp + "in_inter.wav"))
{
   qDebug() << "true";
   QSound::play(temp + "in_inter.wav");
}
else
   qDebug() << QString("error copy sound. Path %1!").arg(temp + "in_inter.wav");

Спасибо! Все оказалось очень просто.

Код:
QFile file("://ir_inter.wav");
    QTemporaryFile ptemp;
    if(ptemp.open()){
        if(file.copy(ptemp.fileName() + "ir_inter.wav")){
            QSound::play(ptemp.fileName() + "ir_inter.wav");
        }
    }
    file.close();
    ptemp.close();


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 27, 2012, 15:03
Кхм. Вы попробуйте так с каким нить файлом где то в полминуты длиной сделать.

Не полетит в тартарары из-за закрытия QTemporalityFiles?

Проще выражаясь - когда удалится ptemp, QSound будет продолжать его проигрывать. Криков не будет?



Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 15:10
Кхм. Вы попробуйте так с каким нить файлом где то в полминуты длиной сделать.

Не полетит в тартарары из-за закрытия QTemporalityFiles?

Проще выражаясь - когда удалится ptemp, QSound будет продолжать его проигрывать. Криков не будет?


Если не ошибаюсь то после закрытия ptemp, временный файл уничтожается. В моём случае имеется маленький звуковой файл, для оповещения. Сама реализация находится в слоте.
Можно конечно сделать уничтожение темпа при закрытии приложения.
Ну с файлами большого размера, такой финт конечно не прокатит я думаю, копирование будет создавать задержку или я ошибаюсь?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 27, 2012, 15:25
Ну до мегабайта копирование ничего не будет создавать.
А вот попортиться звук может :) Вы лучше попробуйте и отпишите :)

PS по идее темповый файл должен умирать, но возможно он останется. И будет лежать там даже после закрытия программы. Так можно и винт захламить :D


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 15:40
Ну до мегабайта копирование ничего не будет создавать.
А вот попортиться звук может :) Вы лучше попробуйте и отпишите :)

PS по идее темповый файл должен умирать, но возможно он останется. И будет лежать там даже после закрытия программы. Так можно и винт захламить :D


Вставил 4мб мп3 файл (wav файлов больших не нашлось). Как оказалось темповые файлы не удаляются и складируются. Файл скопировался в темп, естественно QSound мп3 не поддерживает.
Запустил скопированный мп3 из темпа, ничего не попорчено, даже теги сохранены.
-----------------
Не могу понять, как удалить темп файл, у QTemporaryFile remove() нету, файл должен удаляться с закрытием темпа. Пробовал ставить setAutoRemove(true) - все равно не удаляется.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: kuzulis от Декабрь 27, 2012, 16:55
Цитировать
Не могу понять, как удалить темп файл, у QTemporaryFile remove() нету,
Зато у QFile есть ;)

Надо наверно сначала закрыть QTemporaryFile, а потом удалить через QFile.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 17:42
Цитировать
Не могу понять, как удалить темп файл, у QTemporaryFile remove() нету,
Зато у QFile есть ;)

Надо наверно сначала закрыть QTemporaryFile, а потом удалить через QFile.

Не получается. Что не так?
Код:
QFile file("://ir_inter.wav");
    QTemporaryFile ptemp;
    if(ptemp.open()){
        if(file.copy(ptemp.fileName() + ".wav")){

             QSound::play(ptemp.fileName() + ".wav");

                    }
    }
     QString str = ptemp.fileName();
    str += ".wav";
    file.close();
    ptemp.close();
    QFile::remove(str);


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 27, 2012, 17:51
А разве filename возвращает полный путь? Хотя мб мб


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 17:57
А разве filename возвращает полный путь? Хотя мб мб

дебаг выводит абсолютный путь. Не пойму в чем проблема кроется.

Вычитал, что при копировании из ресурсов, файлу ставится флаг read only. Как можно изменить атрибуты у файла?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: kambala от Декабрь 27, 2012, 18:11
Разве можно открыть дескриптор несуществующего файла на чтение, записать этот файл сторонним способом и потом читать из открытого дескриптора? Или я просто чего-то не понимаю во временных файлах (никогда ими не пользовался, все руками делал)?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Alex Custov от Декабрь 27, 2012, 19:27
Не получается. Что не так?
Код:
QFile file("://ir_inter.wav");
    QTemporaryFile ptemp;
    if(ptemp.open()){
        if(file.copy(ptemp.fileName() + ".wav")){

             QSound::play(ptemp.fileName() + ".wav");

                    }
    }
     QString str = ptemp.fileName();
    str += ".wav";
    file.close();
    ptemp.close();
    QFile::remove(str);

Ты какую-то херню написал, сам подумай. Ты открываешь временный файл, а потом копируешь данные в совершенно другой файл (file.copy(ptemp.fileName() + ".wav")).


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 19:46
Не получается. Что не так?
Код:
QFile file("://ir_inter.wav");
    QTemporaryFile ptemp;
    if(ptemp.open()){
        if(file.copy(ptemp.fileName() + ".wav")){

             QSound::play(ptemp.fileName() + ".wav");

                    }
    }
     QString str = ptemp.fileName();
    str += ".wav";
    file.close();
    ptemp.close();
    QFile::remove(str);

Ты какую-то херню написал, сам подумай. Ты открываешь временный файл, а потом копируешь данные в совершенно другой файл (file.copy(ptemp.fileName() + ".wav")).
Создаю объект временного файла ptemp, потом копирую в него file.  В какой тут еще другой файл можно копировать? К тому же это работает. Вопрос в том, как удалить временный файл,
после его закрытия, учитывая что после копирования у файла стоит атрибут Read only?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 27, 2012, 20:06
Открой свой разум.
Смотри
Код:
 QString str = ptemp.fileName();
// ты получил имя созданного файла. Полное имя. НАИБОЛЕЕ ПОЛНОЕ. Полнее не бывает.
//допустим это имя "qt_temp.wav"
    str += ".wav";
//А этой строкой ты добавляешь к ПОЛНОМУ названию ещё 1 расширение.
// И получаешь "qt_temp.wav.wav"
"qt_temp.wav" НЕ РАВНО "qt_temp.wav.wav"


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 20:13
Открой свой разум.
Смотри
Код:
 QString str = ptemp.fileName();
// ты получил имя созданного файла. Полное имя. НАИБОЛЕЕ ПОЛНОЕ. Полнее не бывает.
//допустим это имя "qt_temp.wav"
    str += ".wav";
//А этой строкой ты добавляешь к ПОЛНОМУ названию ещё 1 расширение.
// И получаешь "qt_temp.wav.wav"
"qt_temp.wav" НЕ РАВНО "qt_temp.wav.wav"
fileName() не возвращает расширение.  Вот
Код:
//До присвоения расширения str += ".wav";
"C:/Users/Use/AppData/Local/Temp/qt_temp.Hp5936"
//После присвоения  str += ".wav";
"C:/Users/Use/AppData/Local/Temp/qt_temp.Hp5936.wav"


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellraiser от Декабрь 27, 2012, 20:49
Плейер проигрывает не по расширению, а по заголовку. Не все-ли равно какое расширение (или его отсутствие) у временного файла?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 27, 2012, 23:34
Переделал копирование файла в обычный QFile.
Код:
QFile file("://ir_inter.wav");
    QFile temp;
    QString str = QDir::toNativeSeparators(QDir::tempPath()) + QDir::separator();
    temp.setFileName(str);
    qDebug() << str;

        if(file.copy(str+="qt_tep")){
                    QSound::play(str);
                                }
    file.close();
    temp.close();
    QFile::remove(str);
Тут все хорошо. Но, файл не удаляется, потому что имеет атрибут read only. Пробовал через setPermission изменить атрибут, но ничего не получается.
Как вообще через Qt, можно изменить атрибуты файла в NTFS файловой системе?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: kambala от Декабрь 27, 2012, 23:39
только через WinAPI раз setPermission не помогает.

может он ридонли потому, что твой исходный файл такой? или заключение файла в ресурсы делает его таким?

как вариант — копируй содержимое файла, а не сам файл.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 28, 2012, 06:54
Файл в ресурсах рид онли :) эт я как то раз уже проверял.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: LisandreL от Декабрь 28, 2012, 08:19
Я думаю ридонли тут не при чём. Просто проигрывание не успевает выполниться и «держит» файл.
Для проверки после play поставьте слип длинной больше чем длина аудио.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 28, 2012, 09:53
Я думаю ридонли тут не при чём. Просто проигрывание не успевает выполниться и «держит» файл.
Для проверки после play поставьте слип длинной больше чем длина аудио.

Уже проверялось - результат тот же, даже если просто создавать файл и не проигрывать его.
Рид онли не дает удалить файл, я уверен. Тут как писали выше, 2 варианта: 1. копировать данные из файла в файл 2. воспользоваться winapi.
Очень интересно, как реализовать первый вариант, ибо слабо представляю как это сделать.
------------
Реализовал снятие атрибута через winapi - теперь файл без проблем удаляется.
Код:
QFile file("://ir_inter.wav");
    QFile temp;
    QString str = QDir::toNativeSeparators(QDir::tempPath()) + QDir::separator();
    temp.setFileName(str);
            if(file.copy(str+="qt_tep")){
            qDebug() << str;
            QSound::play(str);
            qDebug() << "true";
                    }
   std::wstring wpath = str.toStdWString();
   const wchar_t* pchar = wpath.c_str();
   SetFileAttributes(pchar, FILE_ATTRIBUTE_NORMAL);

    file.close();
    temp.close();
    QFile::remove(str);


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: LisandreL от Декабрь 28, 2012, 10:23
Только что проверил remove с setPermissions работает:
Код
C++ (Qt)
       QFile file( "C:\\1.txt" );
       qDebug() << file.setPermissions( QFile::WriteUser );
       qDebug() << file.remove();


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 28, 2012, 10:28
Только что проверил remove с setPermissions работает:
Код
C++ (Qt)
       QFile file( "C:\\1.txt" );
       qDebug() << file.setPermissions( QFile::WriteUser );
       qDebug() << file.remove();

перед этим, на файл поставили атрибут рид онли?  ;D


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Пантер от Декабрь 28, 2012, 10:30
С каких это пор пермижены файла запрещают его удалять? Удаление файла - операция над каталогом, в котором файл этот находится, и тут важны пермижены каталога.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Пантер от Декабрь 28, 2012, 10:35
Попробуй так.

Код
C++ (Qt)
const QString outputFile = QDir::tempPath() + "/ir_inter.wav";
QFile::copy ("://ir_inter.wav", outputFile);
QSound::play(outputFile);
QFile::remove(str);
 


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 28, 2012, 11:14
Попробуй так.

Код
C++ (Qt)
const QString outputFile = QDir::tempPath() + "/ir_inter.wav";
QFile::copy ("://ir_inter.wav", outputFile);
QSound::play(outputFile);
QFile::remove(str);
 
Не удаляется. Все таки нужно снимать атрибут рид онли.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: LisandreL от Декабрь 28, 2012, 11:23
перед этим, на файл поставили атрибут рид онли?  ;D
Разумеется. Без этого работает и без второй строки.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 28, 2012, 11:50
перед этим, на файл поставили атрибут рид онли?  ;D
Разумеется. Без этого работает и без второй строки.
Хм.  Точно работает. Похоже я что то неправильно делал. Но почему в документации написано, что этот метод не работает с NTFS, или я не так понял смысл описания.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Пантер от Декабрь 28, 2012, 11:52
Винда - такая винда. Действительно, есть косяк. Кьют юзает функцию DeleteFile (http://msdn.microsoft.com/ru-ru/library/windows/desktop/aa363915(v=vs.85).aspx), в которой сказано
Цитировать
To delete a read-only file, first you must remove the read-only attribute.
В Линухе, как я и говорил, все пучком.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 28, 2012, 11:56
С каких это пор пермижены файла запрещают его удалять? Удаление файла - операция над каталогом, в котором файл этот находится, и тут важны пермижены каталога.

Какой метод отвечает за пермижены каталога? Я в доке не могу найти


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Пантер от Декабрь 28, 2012, 12:28
С каких это пор пермижены файла запрещают его удалять? Удаление файла - операция над каталогом, в котором файл этот находится, и тут важны пермижены каталога.

Какой метод отвечает за пермижены каталога? Я в доке не могу найти
На сколько я помню, в Кьюте этого нет.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Bepec от Декабрь 28, 2012, 12:32

Провел эксперимент.
При паузе в 2 мс после вызова QSound файл размером в 25 секунд прекрасно удаляется.

Если паузу не ставить, временный файл не удаляется.

Порывшись в исходниках становиться ясно, что sound вызывает апишную ф-цию, которая считывает файл в память, а потом ужо играет :)

Если дать время функции считать файл (1 мс моей системе было достаточно), то всё происходит без сучка.

PS Пантер, удалять не позволяют (в Windows) именно разрешения файла. Для папки могут быть ограничены только права доступа, которые к теме отношения не имеют.


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: Hellrider от Декабрь 28, 2012, 12:57

Провел эксперимент.
При паузе в 2 мс после вызова QSound файл размером в 25 секунд прекрасно удаляется.

Если паузу не ставить, временный файл не удаляется.

Порывшись в исходниках становиться ясно, что sound вызывает апишную ф-цию, которая считывает файл в память, а потом ужо играет :)

Если дать время функции считать файл (1 мс моей системе было достаточно), то всё происходит без сучка.

PS Пантер, удалять не позволяют (в Windows) именно разрешения файла. Для папки могут быть ограничены только права доступа, которые к теме отношения не имеют.

Если не снять рид онли с файла, даже с паузой не удалиться. Вобщем проблема с удалением решена.
Хотелось бы для "справки" узнать, как именно можно копировать например данные из мп3 файла в пустой созданный файл?


Название: Re: Извлечение ресурса из qrc в QTemporaryFile
Отправлено: kambala от Декабрь 28, 2012, 13:20
QFile::read()/write() (для небольших файлов можно и readAll()) или QDataStream