QFileInfo::completeSuffix()

2025-05-31

QFileInfo::completeSuffix()は、QtのQFileInfoクラスのメンバー関数で、ファイル名の完全な拡張子QString型で返します。

QFileInfoクラスについて

QFileInfoクラスは、ファイルシステム上のファイルやディレクトリに関する情報(名前、パス、サイズ、最終更新日時、パーミッションなど)を取得するための、OSに依存しないAPIを提供します。

completeSuffix()の機能

通常、ファイルには.txt.zipなどの拡張子がありますが、中には.tar.gzのように複数のドットで区切られた拡張子を持つファイルもあります。

  • completeSuffix() メソッドは、ファイル名の最初のドット以降のすべての部分(例: archive.tar.gz の場合、tar.gz)を返します。
  • suffix() メソッドは、ファイル名の最後のドット以降の部分(例: archive.tar.gz の場合、gz)を返します。

使用例

#include <QCoreApplication>
#include <QFileInfo>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFileInfo fi("/tmp/document.pdf");
    qDebug() << "File: " << fi.fileName(); // 出力: "document.pdf"
    qDebug() << "Suffix: " << fi.suffix();   // 出力: "pdf"
    qDebug() << "Complete Suffix: " << fi.completeSuffix(); // 出力: "pdf"

    QFileInfo fi2("/home/user/archive.tar.gz");
    qDebug() << "\nFile: " << fi2.fileName(); // 出力: "archive.tar.gz"
    qDebug() << "Suffix: " << fi2.suffix();   // 出力: "gz"
    qDebug() << "Complete Suffix: " << fi2.completeSuffix(); // 出力: "tar.gz"

    QFileInfo fi3("myimage"); // 拡張子がないファイル
    qDebug() << "\nFile: " << fi3.fileName(); // 出力: "myimage"
    qDebug() << "Suffix: " << fi3.suffix();   // 出力: "" (空文字列)
    qDebug() << "Complete Suffix: " << fi3.completeSuffix(); // 出力: "" (空文字列)

    return a.exec();
}


QFileInfo::completeSuffix() 自体は非常にシンプルな関数であり、直接的なエラー(クラッシュなど)を引き起こすことは稀です。しかし、その戻り値を誤解したり、ファイルの特性を考慮しなかったりすることで、論理的なエラーや意図しない挙動が発生することがあります。

拡張子がないファイルの場合

エラー/問題点
拡張子を持たないファイル(例: READMEMakefileなど)に対して completeSuffix() を呼び出すと、空の文字列 ("") が返されます。これを考慮せずに拡張子があるものとして処理を進めると、後続の処理で問題が発生する可能性があります。

トラブルシューティング
completeSuffix() の戻り値が空文字列であるかどうかを常にチェックし、適切な処理を行うようにします。

QFileInfo fi("my_document"); // 拡張子なし
if (fi.completeSuffix().isEmpty()) {
    qDebug() << "このファイルには拡張子がありません。";
    // 拡張子がない場合の処理
} else {
    qDebug() << "拡張子: " << fi.completeSuffix();
}

ディレクトリの場合

エラー/問題点
QFileInfo オブジェクトがディレクトリを指している場合、completeSuffix() は空の文字列を返します。ファイルだと思って拡張子を処理しようとすると、期待しない結果になります。

トラブルシューティング
completeSuffix() を呼び出す前に、QFileInfo::isFile() メソッドで対象がファイルであるかを確認するのが良いプラクティスです。

QFileInfo fi("/home/user/my_directory"); // ディレクトリ
if (fi.isDir()) {
    qDebug() << "これはディレクトリです。拡張子はありません。";
    // ディレクトリの場合の処理
} else if (fi.isFile()) {
    qDebug() << "拡張子: " << fi.completeSuffix();
}

パスにドットが含まれるが拡張子ではない場合

エラー/問題点
ファイル名以外のパスの部分にドットが含まれている場合、completeSuffix() はあくまでファイル名における最初のドット以降を対象とします。例えば、/path/to/my.folder/document.txt の場合、completeSuffix()txt を返します。これは期待通りですが、パス全体を文字列操作で解析している場合に混同される可能性があります。

トラブルシューティング
QFileInfo はファイル名とパスを正確に分離して処理してくれるため、このような状況ではQFileInfoの他のメソッド(fileName(), path()など)と組み合わせて使用することで、意図しない解釈を避けることができます。

特殊なファイル名の場合(隠しファイルなど)

エラー/問題点
Linux/Unix系システムでは、ファイル名が . で始まるファイルは隠しファイルとして扱われます(例: .bashrc)。この場合、completeSuffix()bashrc を返します。これは技術的には正しい動作ですが、ユーザーが「拡張子」と認識しているものとは異なる可能性があります。

トラブルシューティング
隠しファイルの拡張子を処理する必要がある場合は、この挙動を理解しておく必要があります。もし .bashrcbashrc を「拡張子」として扱いたくない場合は、特別なロジックを追加して最初のドットをスキップするなどの処理を行う必要があります。しかし、通常は completeSuffix() の戻り値をそのまま利用しても問題ない場合が多いです。

Windowsのショートカット (.lnk) の場合

エラー/問題点 (Qtのバージョンによる)
過去のQtのバージョンでは、Windowsのショートカットファイル(.lnk)を通常のファイルとして扱い、その .lnk を拡張子として返すことがありました。しかし、最近のQtのバージョンでは、シンボリックリンクとして扱われ、そのターゲットの情報を取得するようになっています(symLinkTarget()など)。

トラブルシューティング
使用しているQtのバージョンとOSの挙動を確認し、QFileInfo::isSymLink()QFileInfo::symLinkTarget() といった関数も考慮して、ショートカットファイルを適切に処理するようにします。

ファイルが存在しない場合

エラー/問題点
QFileInfo オブジェクトが指すファイルが実際に存在しない場合でも、completeSuffix() はファイル名から計算された拡張子を返します。例えば、QFileInfo("non_existent_file.zip")completeSuffix()zip を返します。ファイルが存在しないのに拡張子があるように見えてしまい、後続のファイル操作でエラーになる可能性があります。

トラブルシューティング
ファイルが存在することを確認してから拡張子を処理することが重要です。QFileInfo::exists() メソッドで存在チェックを行います。

QFileInfo fi("non_existent_file.zip");
if (!fi.exists()) {
    qDebug() << "ファイルが存在しません。";
    // ファイルが存在しない場合の処理
} else {
    qDebug() << "拡張子: " << fi.completeSuffix();
}

QFileInfo::completeSuffix() は、ファイル名の拡張子を柔軟に取得できる強力なツールですが、その戻り値の解釈や、対象がファイルであるかどうかの確認を怠ると、予期せぬ挙動につながることがあります。

  • 拡張子がない場合 (isEmpty()) を考慮する
  • ファイルかディレクトリかを確認する (isFile(), isDir())
  • 常に存在チェックを行う (exists())


基本的な使用例

最もシンプルな使用方法です。

#include <QCoreApplication>
#include <QFileInfo>
#include <QDebug> // デバッグ出力用

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 例1: 一般的なファイル名
    QFileInfo file1("document.pdf");
    qDebug() << "ファイル名:" << file1.fileName();
    qDebug() << "完全な拡張子 (completeSuffix):" << file1.completeSuffix(); // 出力: "pdf"
    qDebug() << "拡張子 (suffix):" << file1.suffix();                     // 出力: "pdf"

    qDebug() << "--------------------";

    // 例2: 複数のドットを含む拡張子
    QFileInfo file2("archive.tar.gz");
    qDebug() << "ファイル名:" << file2.fileName();
    qDebug() << "完全な拡張子 (completeSuffix):" << file2.completeSuffix(); // 出力: "tar.gz"
    qDebug() << "拡張子 (suffix):" << file2.suffix();                     // 出力: "gz"

    qDebug() << "--------------------";

    // 例3: 拡張子のないファイル
    QFileInfo file3("README");
    qDebug() << "ファイル名:" << file3.fileName();
    qDebug() << "完全な拡張子 (completeSuffix):" << file3.completeSuffix(); // 出力: "" (空文字列)
    qDebug() << "拡張子 (suffix):" << file3.suffix();                     // 出力: "" (空文字列)

    qDebug() << "--------------------";

    // 例4: ドットで始まる隠しファイル (Unix/Linux系)
    QFileInfo file4(".bashrc");
    qDebug() << "ファイル名:" << file4.fileName();
    qDebug() << "完全な拡張子 (completeSuffix):" << file4.completeSuffix(); // 出力: "bashrc"
    qDebug() << "拡張子 (suffix):" << file4.suffix();                     // 出力: "bashrc"

    return a.exec();
}

解説

  • .bashrc のような隠しファイルの場合、completeSuffix()bashrc を返します。
  • 拡張子がない場合は、両方とも空文字列を返します。
  • suffix() はファイル名の最後のドットから末尾までの文字列を返します。
  • completeSuffix() はファイル名の最初のドットから末尾までの文字列を返します。

ファイルの種類判別に応用する例

取得した完全な拡張子を使って、ファイルの種類を判別する例です。

#include <QCoreApplication>
#include <QFileInfo>
#include <QDebug>
#include <QString>

void identifyFileType(const QString& filePath) {
    QFileInfo fileInfo(filePath);

    qDebug() << "--- ファイル:" << filePath << " ---";

    // ファイルが存在するか確認
    if (!fileInfo.exists()) {
        qDebug() << "エラー: ファイルまたはディレクトリが存在しません。";
        return;
    }

    // ディレクトリかどうかを確認
    if (fileInfo.isDir()) {
        qDebug() << "これはディレクトリです。";
        return;
    }

    // ファイルの場合のみ拡張子を処理
    if (fileInfo.isFile()) {
        QString completeExt = fileInfo.completeSuffix().toLower(); // 大文字小文字を区別しないように小文字化

        if (completeExt == "zip" || completeExt == "tar.gz" || completeExt == "7z") {
            qDebug() << "これはアーカイブファイルです。";
        } else if (completeExt == "jpg" || completeExt == "png" || completeExt == "gif") {
            qDebug() << "これは画像ファイルです。";
        } else if (completeExt == "txt" || completeExt == "md" || completeExt == "log") {
            qDebug() << "これはテキストファイルです。";
        } else if (completeExt == "pdf") {
            qDebug() << "これはPDFドキュメントです。";
        } else if (completeExt.isEmpty()) {
            qDebug() << "このファイルには拡張子がなく、種類を特定できません。";
        } else {
            qDebug() << "不明なファイルタイプ。完全な拡張子:" << completeExt;
        }
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    identifyFileType("my_archive.tar.gz");
    identifyFileType("image.JPG"); // 大文字の拡張子も考慮
    identifyFileType("document.pdf");
    identifyFileType("notes.txt");
    identifyFileType("program"); // 拡張子なし
    identifyFileType("/home/user/my_folder"); // 存在するディレクトリを仮定
    identifyFileType("non_existent_file.xyz"); // 存在しないファイル

    return a.exec();
}

解説

  • isEmpty() で拡張子がない場合をハンドリングしています。
  • completeSuffix().toLower() を使用して、拡張子の大文字・小文字を区別せずに比較できるようにしています。これにより、JPGjpgとして扱えます。
  • isFile() でファイルであるかを確認し、ファイルの場合のみcompleteSuffix()を呼び出します。
  • isDir() でディレクトリであるかを確認し、ディレクトリの場合は拡張子の処理をスキップします。
  • exists() でファイルまたはディレクトリが存在するかを確認します。

ファイルパスの安全な処理とエラーハンドリング

QFileInfo::completeSuffix() の使用時に考慮すべきエラーケースを含んだ例です。

#include <QCoreApplication>
#include <QFileInfo>
#include <QDebug>
#include <QString>
#include <QDir> // QDir::homePath() のために必要

void processFileWithSuffixCheck(const QString& filePath) {
    QFileInfo fileInfo(filePath);

    qDebug() << "--- 処理対象ファイル:" << filePath << " ---";

    // 1. ファイルが存在するかどうかを確認
    if (!fileInfo.exists()) {
        qDebug() << "エラー: ファイルまたはディレクトリが存在しません。処理をスキップします。";
        return;
    }

    // 2. ディレクトリであるかどうかを確認
    if (fileInfo.isDir()) {
        qDebug() << "注意: これはディレクトリです。拡張子は存在しません。";
        // ディレクトリに対する特定の処理が必要な場合はここに追加
        return;
    }

    // 3. ファイルの場合のみ completeSuffix() を利用
    if (fileInfo.isFile()) {
        QString completeExt = fileInfo.completeSuffix();

        if (completeExt.isEmpty()) {
            qDebug() << "このファイル (" << fileInfo.fileName() << ") には拡張子がありません。";
        } else {
            qDebug() << "ファイル名:" << fileInfo.fileName();
            qDebug() << "完全な拡張子:" << completeExt;

            // 例: 特定の拡張子のファイルをコピーする
            if (completeExt.compare("zip", Qt::CaseInsensitive) == 0) { // 大文字小文字を無視して比較
                QString newFileName = fileInfo.baseName() + "_copy." + completeExt;
                // 仮のコピー先パス (実際には適切なディレクトリを指定してください)
                QString destinationPath = QDir::temp().filePath(newFileName);
                if (QFile::copy(filePath, destinationPath)) {
                    qDebug() << "ファイルをコピーしました:" << destinationPath;
                } else {
                    qDebug() << "ファイルのコピーに失敗しました。";
                }
            }
        }
    } else {
        qDebug() << "これは通常のファイルでもディレクトリでもありません(例: シンボリックリンクなど)。";
        // シンボリックリンクの場合の処理
        if (fileInfo.isSymLink()) {
            qDebug() << "シンボリックリンクのターゲット:" << fileInfo.symLinkTarget();
            // ターゲットのファイル情報を再度取得して処理することも可能
            QFileInfo targetInfo(fileInfo.symLinkTarget());
            if (targetInfo.isFile()) {
                 qDebug() << "ターゲットの完全な拡張子:" << targetInfo.completeSuffix();
            }
        }
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // テスト用のファイルを作成 (一時ディレクトリに)
    QDir tempDir = QDir::temp();
    QString testFilePath1 = tempDir.filePath("test_document.pdf");
    QString testFilePath2 = tempDir.filePath("my_archive.tar.gz");
    QString testFilePath3 = tempDir.filePath("no_extension_file");
    QString testFilePath4 = tempDir.filePath("existing_dir"); // ディレクトリとしてテスト

    QFile file1(testFilePath1);
    file1.open(QIODevice::WriteOnly); file1.close(); // 空のファイルを作成
    QFile file2(testFilePath2);
    file2.open(QIODevice::WriteOnly); file2.close();
    QFile file3(testFilePath3);
    file3.open(QIODevice::WriteOnly); file3.close();
    tempDir.mkdir(testFilePath4); // ディレクトリを作成

    processFileWithSuffixCheck(testFilePath1);
    processFileWithSuffixCheck(testFilePath2);
    processFileWithSuffixCheck(testFilePath3);
    processFileWithSuffixCheck(testFilePath4);
    processFileWithSuffixCheck("/path/to/non_existent_file.xyz"); // 存在しないファイル
    processFileWithSuffixCheck(QDir::homePath()); // ユーザーのホームディレクトリ (ディレクトリ)

    // テストファイルをクリーンアップ
    QFile::remove(testFilePath1);
    QFile::remove(testFilePath2);
    QFile::remove(testFilePath3);
    tempDir.rmdir(testFilePath4);

    return a.exec();
}
  • 一時ファイル
    テスト用に QDir::temp() を使って一時ディレクトリにファイルを作成・削除する例も含まれています。
  • 大文字小文字の比較
    QString::compare()Qt::CaseInsensitive を使うことで、拡張子の大文字小文字を区別せずに比較できます。
  • 種類判別
    fileInfo.isDir() でディレクトリか、fileInfo.isFile() で通常のファイルかを判断し、それぞれ異なる処理パスを設定します。
  • 存在チェック
    fileInfo.exists() を最優先で行い、ファイルが存在しない場合はそれ以上の処理を行いません。


QFileInfo::suffix() を使用する

これは最も直接的な代替手段であり、completeSuffix() との比較でその違いを理解することが重要です。

  • 使い分け
    • 単一の拡張子(例: .pdf, .txt)だけが必要な場合。
    • ファイルのメインのタイプを判別する際に、複合拡張子(例: .tar.gz)の最後の部分(.gz)だけが重要な場合。
  • 機能
    ファイル名の最後のドット以降の文字列(最も一般的な意味での「拡張子」)を返します。

コード例

#include <QCoreApplication>
#include <QFileInfo>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFileInfo fi1("document.pdf");
    qDebug() << "File:" << fi1.fileName() << " Suffix:" << fi1.suffix(); // 出力: "pdf"

    QFileInfo fi2("archive.tar.gz");
    qDebug() << "File:" << fi2.fileName() << " Suffix:" << fi2.suffix(); // 出力: "gz"

    return a.exec();
}

QString::section() や QString::split() を使用して手動で解析する

ファイルパス全体が QString として手元にある場合、文字列操作関数を使って拡張子を抽出することも可能です。これは QFileInfo を使うよりも低レベルなアプローチですが、特定のフォーマットのパスを扱う場合や、ファイルシステムにアクセスせずに文字列情報だけで処理を完結させたい場合に有用です。

  • 使い分け
    • QFileInfo を使用するオーバーヘッドを避けたい場合(非常にパフォーマンスが重要な場面)。
    • パスの特定の部分(例: folder.name/file.extfolder.name の部分)からドットで区切られた情報を取得したい場合。
    • QFileInfo が提供する機能だけでは不十分で、より複雑なパス解析が必要な場合。
  • 機能
    ドットを区切り文字として文字列を分割し、必要な部分を取得します。

コード例 (completeSuffix() の代替として)

#include <QCoreApplication>
#include <QDebug>
#include <QString>

QString getCompleteSuffixManual(const QString& filename) {
    int lastSlash = filename.lastIndexOf('/'); // Unix/Linux系
    #ifdef Q_OS_WIN
    lastSlash = qMax(lastSlash, filename.lastIndexOf('\\')); // Windows系
    #endif

    QString nameWithoutPath = (lastSlash != -1) ? filename.mid(lastSlash + 1) : filename;

    int firstDot = nameWithoutPath.indexOf('.');
    if (firstDot != -1) {
        return nameWithoutPath.mid(firstDot + 1);
    }
    return QString(); // 拡張子がない場合
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString filename1 = "document.pdf";
    qDebug() << "File:" << filename1 << " Complete Suffix (Manual):" << getCompleteSuffixManual(filename1);

    QString filename2 = "archive.tar.gz";
    qDebug() << "File:" << filename2 << " Complete Suffix (Manual):" << getCompleteSuffixManual(filename2);

    QString filename3 = "README";
    qDebug() << "File:" << filename3 << " Complete Suffix (Manual):" << getCompleteSuffixManual(filename3);

    QString filename4 = "/path/to/my.folder/data.txt"; // パスを含む場合
    qDebug() << "File:" << filename4 << " Complete Suffix (Manual):" << getCompleteSuffixManual(filename4);

    return a.exec();
}

解説

  • QFileInfo はOSのパス区切り文字(/\)やファイル名規則を自動的に処理してくれるため、手動解析はより複雑でエラーを起こしやすい傾向があります。特別な理由がない限り、QFileInfo の使用が推奨されます。
  • この手動解析は、まずファイルパスからファイル名部分を抽出し、次にファイル名から最初のドット以降を抽出します。

正規表現を使用する

より複雑なパターンマッチングが必要な場合や、特定のルールに基づいて拡張子を抽出したい場合は、正規表現(QRegularExpression)が強力なツールとなります。

  • 使い分け
    • ファイル名の特定のセグメントを抽出したい場合。
    • 拡張子が特定の文字セットのみを含むことを確認したい場合。
    • QFileInfo や単純な文字列操作では対応できないような、複雑な拡張子パターンを扱う場合。
  • 機能
    定義されたパターンに一致する文字列の部分を抽出します。

コード例

#include <QCoreApplication>
#include <QDebug>
#include <QString>
#include <QRegularExpression>

QString getCompleteSuffixRegex(const QString& filename) {
    // ファイルパスからファイル名部分を抽出
    QFileInfo fi(filename);
    QString baseName = fi.fileName();

    // 正規表現パターン: 最初のドット以降のすべてをキャプチャ
    // ^: 行の始まり
    // [^.]*: ドット以外の文字が0回以上
    // \.: ドット
    // (.*): ドット以降の任意の文字が0回以上 (これが拡張子部分)
    // $: 行の終わり
    QRegularExpression regex("^[^.]*\\.(.*)$");
    QRegularExpressionMatch match = regex.match(baseName);

    if (match.hasMatch()) {
        return match.captured(1); // 最初のキャプチャグループ (.*) を返す
    }
    return QString(); // マッチしない場合(拡張子がない場合)
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString filename1 = "document.pdf";
    qDebug() << "File:" << filename1 << " Complete Suffix (Regex):" << getCompleteSuffixRegex(filename1);

    QString filename2 = "archive.tar.gz";
    qDebug() << "File:" << filename2 << " Complete Suffix (Regex):" << getCompleteSuffixRegex(filename2);

    QString filename3 = "README";
    qDebug() << "File:" << filename3 << " Complete Suffix (Regex):" << getCompleteSuffixRegex(filename3);

    QString filename4 = ".bashrc"; // ドットで始まるファイル
    qDebug() << "File:" << filename4 << " Complete Suffix (Regex):" << getCompleteSuffixRegex(filename4);

    return a.exec();
}

解説

  • ファイル名に複数のドットがある場合、この正規表現は最初のドット以降のすべてを拡張子として扱います(completeSuffix()と同じ挙動)。
  • 正規表現は非常に強力ですが、パターンが複雑になると可読性が低下し、デバッグが難しくなる可能性があります。

QStandardPaths や他のOS固有のAPIを使用する(非推奨)

Qtはクロスプラットフォームなライブラリであるため、通常は QFileInfo のようなQtのAPIを使用することが推奨されます。しかし、非常に特殊な状況や、Qt以外の部分でファイルパスを処理する必要がある場合、OS固有のAPI(例: WindowsのPathCchシリーズ関数、C++17のstd::filesystem)を使用することも可能です。

  • 使い分け
    • 特定のOSに強く依存するアプリケーションで、Qtの依存性を最小限に抑えたい場合。
    • C++17以降を使用しており、std::filesystem の提供する統一されたインターフェースを利用したい場合。
    • ただし、クロスプラットフォーム対応が必要な場合は、QtのQFileInfoを使用すべきです。 OS固有のAPIは移植性が低くなります。
  • 機能
    OSが提供するファイルパス操作機能。
#include <iostream>
#include <string>
#include <filesystem> // C++17

// main関数はQtアプリケーションの一部として動作させても問題ありません
// QCoreApplication a(argc, argv);
// return a.exec(); は省略しています

int main() {
    std::filesystem::path p1("document.pdf");
    std::cout << "File: " << p1.filename() << " Suffix: " << p1.extension() << std::endl; // .pdf

    std::filesystem::path p2("archive.tar.gz");
    // std::filesystem::path::extension() は最後の拡張子のみを返す
    std::cout << "File: " << p2.filename() << " Suffix: " << p2.extension() << std::endl; // .gz

    // completeSuffix() に相当する機能は extension() だけでは直接得られない
    // 複数の拡張子を連結する必要がある
    std::string completeSuffix;
    std::filesystem::path currentPath = p2.filename(); // "archive.tar.gz"
    while (currentPath.has_extension()) {
        std::string ext = currentPath.extension().string(); // .gz, .tar
        if (ext.empty() || ext == ".") break; // 拡張子がないか、隠しファイルの場合
        if (!completeSuffix.empty()) {
            completeSuffix = ext + "." + completeSuffix;
        } else {
            completeSuffix = ext;
        }
        currentPath = currentPath.stem(); // "archive.tar", then "archive"
    }
    std::cout << "File: " << p2.filename() << " Complete Suffix (std::filesystem manual):" << completeSuffix << std::endl;

    return 0;
}

解説

  • QFileInfo::completeSuffix() に相当する機能を得るには、extension()stem() を繰り返し使用して手動で構築する必要があります。
  • std::filesystem::path::extension()QFileInfo::suffix() と同様に、最後の拡張子のみを返します。

QFileInfo::completeSuffix() は、特にファイル名に複数のドットが含まれる場合に、Qtで「完全な拡張子」を簡単に取得できる最も推奨される方法です。

代替手段は以下の状況で検討されます:

  • std::filesystem (C++17)
    Qtの依存を避けたい、またはモダンC++の機能を使いたい場合。ただし、この場合でも completeSuffix() と同等のロジックを自分で実装する必要があります。
  • 正規表現
    非常に複雑な拡張子パターンにマッチさせたい場合。
  • 手動の文字列解析 (QString::section() など)
    QFileInfo のオーバーヘッドを避けたい、またはファイルシステムへのアクセスが不要で、単純な文字列操作で十分な場合。ただし、パスの解析は手動で行うと複雑になりがちです。
  • QFileInfo::suffix()
    単一の(最後の)拡張子のみが必要な場合。