This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Organising files with long filenames

Tags: None
(comma "," separated)
Galim
Registered Member
Posts
12
Karma
0
Hello all,

I have just taught myself C++ and bought a book on Qt, so I thought I would try to do something useful, so please be lenient with me as this is my first ever attempt at a bugfix!

I noticed a lot of errors when organising files with long filenames, and looked up the maximum filename length of various filesystems.  Ext3, XFS, and even ZFS are all limited to 255 characters only, so I realised this was the problem (or  a problem), since I couldn’t spot any system for shortening long filenames.  The ideal solution would be a check box under “details” for truncating long filenames.  However, I thought that the following code might do the trick in organisecollectiondialogue.ui.h:

QString OrganizeCollectionDialog::buildDestination( const QString &format, const MetaBundle &mb ) const
{
    bool isCompilation = false;
    ...
    ...
    ...

--    return result.replace( QRegExp( "/\\.*" ), "/" );
++ result.replace( QRegExp( "/\\.*" ), "/" );
++ QCString resultInUtf8 = result.utf8();//the filename is stored in utf8, and cannot exceed 255 bytes
++ if (resultInUtf8.length() - resultInUtf8.findRev('/') > 254) {//only interested in filename, not path
++ QString extension = result.right(result.length() + 1 - result.findRev('.'));//just assumes there is an extension
++ result = result.left(result.length() - 50);//lop off the last 50 (leaves directory untouched)
++ //We do this to allow a safety margin (a big one) as there may be many multibyte characters taking up
++ //loads of space - we can have up to 50 two-byte characters now, or the rename will still fail.
++ //If we truncate the utf8 string, then that leaves us with the problem of possibly hacking a utf8 char in half.
++ result += extension;//put back extension
++ }
++ return result;
}

I am sure there is a better way to do this, but it is not as simple as just making the name in 'result' less than the limit, as result is a QString, which is unicode, so may exceed 255 bytes of storage, even if result.length() is less than that.  This would certainly fix my problems, as I don’t really mind if my filenames get truncated, as long as I am saved having to manually rename the long ones (I have some over 350 bytes long!).

This does compile, but I have not got around to testing it yet (sorry!) as I am just about to go climbing for a few weeks, so I probably will not reply for weeks, but I am interested in comment (if I make it back, of course).

Thanks everyone for tolerating a silly newbie, and making such great software.

Nicholas
stokedfish
Karma
0
http://www.krename.net/  ;)

or tag your files and auto-rename 'em with easytag...
Galim
Registered Member
Posts
12
Karma
0
I know you can use KRename (I already have it and use it) but what is the point of putting organise features into amaroK if you tell people not to use them on the amaroK fora?

I could not instantly see a way of using KRename to lengthen filenames - obvious strings like [[flacTitle]1-255] do not work, and if left to its own devices it will choke on 300B filenames and report errors rather than truncating them.

Anyway, you can ignore the previous code—this stuff here actually works.

Code: Select all
    ...
    ...
    Amarok::QStringx formatx( format );
    QString result = formatx.namedOptArgs( args );
    if( result.startsWith( folderCombo->currentText() ) )
    {
        QString tail = result.mid( folderCombo->currentText().length() );
        if( !tail.startsWith( "/" ) )
            tail.prepend( "/" );
        result = folderCombo->currentText() + tail.replace( QRegExp( "/\\.*" ), "/" );
    }
    else result.replace( QRegExp( "/\\.*" ), "/" );

    QCString resultInUtf8 = result.utf8();//the filename is stored in utf8, and cannot exceed 255 bytes
    if (resultInUtf8.length() - resultInUtf8.findRev('/') > 254) {
        result = result.left(result.length() +254 - args["filetype"].length()
            - ( resultInUtf8.length() - resultInUtf8.findRev('/') ));
        //lop off charcters down to about 200
        //We do this to allow a safety margin (a big one) as there may be many multibyte characters taking up
        //loads of space - we can have up to 50 here.
        //If we truncate the utf8 string, that leaves us with the problem of possibly hacking a utf8 char in half.
        result += "." + args["filetype"];//put back extension
    }
    return result;
}


You might not find this very useful, but it works for me now, so someone else might be interested to see this merged into amarok.

Essentially, we use the utf string to find out how many bytes to remove, then take off that number of characters, so the filename might not be the maximal length, but it is close enough.  A little look at other filesystems shows that actually reiserfs beats the ridiculously large zfs on filename length, as it can have up to 4095 byte names.

Last edited by Galim on Fri Jul 27, 2007 7:39 pm, edited 1 time in total.


Bookmarks



Who is online

Registered users: abc72656, Bing [Bot], daret, Google [Bot], Sogou [Bot], Yahoo [Bot]