1

I just copied all my cds to my computer with a program called "Sound Juicer". It works fine, it creates for each artist a folder and it it for each album another folder. And of course in these folders the mp3 files.

The problem is I want the Tracknumber, the Artist and then the Tracktitle as name for my songs. What Sound Juicer does is adding d1t in front of the file which stands for "Disk 1 Title".

I'm a programmer so I used this problem to practice a little bit. This works :

void MainWindow::rename( const QString & text )
{
    static int _files = 0;

    QDir dir( text );
    QFileInfoList a = dir.entryInfoList( QDir::Files | QDir::Dirs );
    for( int i = 2; i < a.size(); i++ )
    {
        static QDir tmp;

        if( a.at( i ).isDir() )
            rename( a.at( i ).absoluteFilePath() );

        if( a.at( i ).fileName().startsWith( "d1t" ) || a.at( i ).fileName().startsWith( "d2t" ) )
        {
            QString newFile = a.at( i ).fileName().remove(0,3);
            tmp = a.at( i ).dir();

            if( !tmp.rename( a.at( i ).fileName(), newFile ) )
                qDebug() << "Failed";

            _files++;
        }
    }
}

It checks a directory, selects the first file or directory and checks what it is. If it is a directory it calls itself (recursion) and starts again until he finds some files or no more directories exist. If a file is found, it renames it and adds 1 to the file counter.

However, it only renamed all files in the first 2 or 3 directories. After that it caused a SIGSEGV. Does anyone knows whats wrong?

Example of my directories :

1 Directory ("Sum 41") -> 1 Subdirectory ("All Killer No Filler") -> Files "d1t01. Sum 41 - Introduction to Destruction.mp3" etc. ... 2 Subdirectory ("Blah Blah") -> Files ...

2 Directory ("Shinedown") -> 1 Subdirectory ("Sound of Madness") -> Files d1t01. Shinedown - Devour.mp3 etc...

3 Directory ("Guns N’ Roses") -> Subdirectory ("Blah Blah") -> files ... Subdirectory ("Blah ") -> files ...

4

2 回答 2

0

使用 static 你试图告诉编译器你只想要整个程序中的一个实例,但是你把它放在一个 for 循环中。那不是很干净。在这种情况下,静态是无用的。由于静态初始化混乱问题,静态也可能导致问题。因此,如果您真的不需要静态初始化,请将其删除并使其成为本地变量或类变量。

重写您的方法,以便能够更好地阅读它,我看到您递归地调用该方法,这可能导致无限循环。

另一个问题是你的文件变量,它的目的是什么?

void MainWindow::rename( const QString & text ) {
    int files = 0;

    QDir dir(text); // does QDir also accept wrong paths?
    QFileInfoList list = dir.entryInfoList(QDir::Files|QDir::Dirs); // does it return a list in all cases?
    foreach (QFileInfo entry, list) {
        if (entry.isDir()) {
            //is everything always ok when doing this?
            // POTENTIAL infinite loop 
            rename(entry.absoluteFilePath());
        }
        else {
            QString fileName = entry.fileName();
            if(fileName.startsWith("d1t") || fileName.startsWith("d2t")) {
                if (!entry.dir().rename(fileName, fileName.remove(0,3))) qDebug() << "Failed";
                files++;
            }
        }
    }
}
于 2013-10-10T17:41:23.377 回答
-1

我在 fonZ 和 Frank Osterfeld 的帮助下以某种方式修复了它。我终于创建了一个 GUI 来选择一条路径。然而,我已经做到了。这段代码查找所有目录而不会导致无限循环或溢出(到目前为止)。问题在于 QDir 和 QFileInfo 获取路径的函数。我玩了一段时间,结果出来了:

void MainWindow::rename( const QString& path )
{
    //If invalid path return
    if( path.isEmpty() || ( !QDir( path ).exists() ) )
        return;

    //entryInfoList( QDir::NoDotAndDotDot ) doesn't work. 
    QFileInfoList fileList = QDir( path ).entryInfoList();

    foreach (QFileInfo entry, fileList ) {

        //Eliminating wrong paths
        if( entry.isDir() ){
            if( entry.filePath().endsWith(".") )
                continue;

            //Start function again with new directory
            rename( entry.filePath() );
        }
        else{

            QString fileName = entry.fileName();
            if( fileName.startsWith( "d1t" ) || fileName.startsWith( "d2t" ) ){
                //Remove those characters
                fileName.remove( 0, 3 );

                //If renaming is successful, increment the successful files
                //If not, increment the failed files and print an error
                if( entry.dir().rename( entry.fileName(), fileName ) )
                    files++;
                else{
                    addError( "Could not rename " + entry.fileName() + " to " + fileName );
                    filesFailed++;
                }

            }
        }

    }
}
于 2013-10-10T19:15:00.160 回答