Qt   言語   ファイルとディレクトリQt6対応

ホーム   C/C++チュートリアル  

このコーナーは、Qt6 のみに対応しています。

ファイルとディレクトリ

Qt にはファイルとディレクトリを操作する、QFile、QDir、AFileInfo クラスがあります。

QFile は、ファイルの読み書きや、その他の操作をします。

QDir は、ディレクトリの操作をします。

QFileInfo はファイルの情報を取得します。

ファイルサイズの取得

この章では、filedir ディクトリに filedir.cpp を作成して、作業を進めていきます。

filedir.cpp


#include <QTextStream>
#include <QFileInfo>

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

  QTextStream out{stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);

  if (argc != 2) {

    qWarning("使い方: fildir ファイル名");
    return 1;
  }

  QString filename = argv[1];

  QFile f{filename};

  if (!f.exists()) {

    qWarning("ファイルが存在しません。");
    return 1;
  }

  QFileInfo fileinfo{filename};

  qint64 size = fileinfo.size();

  QString str = "ファイルのサイズは%1バイトです。";

  out << str.arg(size) << Qt::endl;

  return 0;
}


コード説明

  1. if (argc != 2)
    argc にはコマンドラインで起動した場合の文字列の数が入ります。1番目には アプリ名が入りますので、2番目がなければファイル名が指定されていないことになります。
  2. QString filename = argv[1];
    argv にはコマンドラインで起動した場合の文字列の配列が入ります。1番目 (つまり2番目) がファイル名のはずです。
  3. QFile f{filename}
    QFile のインスタンス f をファイル名のファイルで初期化して作ります。
  4. if (!f.exists())
    ファイルが存在しているか確かめています。
  5. QFileInfo fileinfo{filename};
    QFileInfo のインスタンス fileinfo をファイル名のファイルで初期化して作ります。

ビルド

filedir ディレクトリで作業を続けます。


// プロジェクトを作ります。
qmake -project

// Windows の場合は出来上がった datetime.pro の末尾に次の一行を追加します。
CONFIG += console

// Makefile を作ります。
qmake

// 実行ファイルを作ります。
// Mac Linux の場合は make します。
make

// Windows の場合は nmake します。make じゃなく nmake です。
nmake

// エラーが表示されたら、filedir.cpp を見直して、make あるいは nmake する作業を繰り返します。

実行


// Mac の場合は datetime ディレクトリに filedir.app ができあがります。
// GUI アプリケーションならこれをダブルクリックすると起動できますが、
// 今回はコマンドラインアプリなので次のようにして実行します

./filedir.app/Contents/MacOS/filedir

// 結果
使い方: fildir ファイル名

./filedir.app/Contents/MacOS/filedir f

// 結果
ファイルが存在しません。

./filedir.app/Contents/MacOS/filedir ../../../filedir

// 結果
ファイルのサイズは51432バイトです。

// Linux の場合には filedir ディレクトリに filedir という実行ファイルが出来上がっていますのでそれをそのまま実行します
./filedir

// 結果
使い方: fildir ファイル名

./filedir f

// 結果
ファイルが存在しません。

/filedir Makefile

// 結果
ファイルのサイズは14880バイトです。

// Windows の場合には filedir ディレクトリの中の release ディレクトリに filedir.exe が出来上がっています。
// release ディレクトリに移動して、filedir.exe を実行します。
filedir

// 結果
使い方: fildir ファイル名

filedir f

// 結果
ファイルが存在しません。

filedir filedir.obj

// 結果
ファイルのサイズは11238バイトです。

ファイルの読み込み

まず次のファイルを filedir ディレクトリに作ります。

日本語.txt


赤い羽根
白い雲
遠くの山
青い海
綺麗な湖

そして、filedir.cpp を次のように記述します。

filedir.cpp


#include <QTextStream>
#include <QFile>

int main(void) {

  QTextStream out{stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  QFile f {"日本語.txt"};
  
  if (!f.open(QIODevice::ReadOnly))
  {
    qWarning ("読み取り用としてファイルを開けませんでした。");
    return 1;
  }
  
  QTextStream in {&f};
  
  while (!in.atEnd())
  {
    QString line = in.readLine();
    out << line << Qt::endl;
  }
  
  f.close();

  return 0;
}

コード説明

  1. QFile f {"日本語.txt"};
    QFile のインスタンス f を 日本語.txt ファイルで初期化して作っています。
  2. if (!f.open(QIODevice::ReadOnly))
    f を読み込み用として開いています。
  3. QTextStream in {&f};
    QTextStream のインスタンス in を f で初期化して作っています。 QTextStream は テキストの入出力を担当するクラスです。 画面に対しても入出力ですし、ファイルに対しても入出力です。
  4. while (!in.atEnd())
    in インスタンスが終わりでなければ while ループを続けます。
  5. QString line = in.readLine();
    in から一行だけ読み込んでいます。
  6. out << line << Qt::endl;
    読み込んだ一行をターミナルへ出力しています。
  7. f.close();
    ファイルを閉じています。

ビルド

filedir ディレクトリで作業を続けます。


// プロジェクトを作ります。
qmake -project

// Windows の場合は出来上がった datetime.pro の末尾に次の一行を追加します。
CONFIG += console

// Makefile を作ります。
qmake

// 実行ファイルを作ります。
// Mac Linux の場合は make します。
make

// Windows の場合は nmake します。make じゃなく nmake です。
nmake

// エラーが表示されたら、filedir.cpp を見直して、make あるいは nmake する作業を繰り返します。

実行


// Mac の場合は datetime ディレクトリに filedir.app ができあがります。
// GUI アプリケーションならこれをダブルクリックすると起動できますが、
// 今回はコマンドラインアプリなので次のようにして実行します

./filedir.app/Contents/MacOS/filedir

// 結果
赤い羽根
白い雲
遠くの山
青い海
綺麗な湖


// Linux の場合には filedir ディレクトリに filedir という実行ファイルが出来上がっていますのでそれをそのまま実行します
./filedir

// 結果
赤い羽根
白い雲
遠くの山
青い海
綺麗な湖

// Windows の場合は filedir ディレクトリの中の release ディレクトリに filedir.exe が出来上がっています。
// まず、日本語.txt を release ディレクトリに移動してください。
// そしてコマンドプロンプトも release ディレクトリに移動して、filedir.exe を実行します。
filedir

// 結果
赤い羽根
白い雲
遠くの山
青い海
綺麗な湖

ファイルの書き込み

filedir.cpp


#include <QTextStream>
#include <QFile>

int main(void) {

  QTextStream out{stdout}; // 記述しても記述しなくても結果は同じ
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  QString filename = "日本語2.txt";
  QFile f {filename};
  
  if (f.open (QIODevice::WriteOnly))
  {
    QTextStream out {&f};
    out << "春はあけぼの" << Qt::endl;
    out << "春眠暁を覚えず" << Qt::endl;
    out << "春の海 終日のたり のたりかな" << Qt::endl;
    f.close();
  }
  else
  {
    qWarning ("ファイルを開けませんでした。");
  }
  
  return 0;
}

コード説明

  1. if (f.open (QIODevice::WriteOnly))
    ファイルを書き込み専用として開いています。
  2. QTextStream out {&f};
    テキストストリームがファイルに対して out という名前で使うと宣言しています。

実行と結果


// Mac nad Linux
make

// Windows
nmake

// Mac 実行
./filedir.app/Contents/MacOS/filedir

// 結果
// cat 日本語2.txt
春はあけぼの
春眠暁を覚えず
春の海 終日のたり のたりかな

// Linux 実行
./filedir

// 結果
// cat 日本語2.txt
春はあけぼの
春眠暁を覚えず
春の海 終日のたり のたりかな

ファイルのコピー

filedir.cpp


#include <QTextStream>
#include <QFileInfo>

int main(int argc, char **argv)
{
  QTextStream out{stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  if (argc != 3)
  {
    qWarning ("使い方 filedir 元ファイル コピー先ファイル");
    return 1;
  }
  
  QString moto = argv[1];
  if (!QFile {moto}.exists())
  {
    qWarning ("元ファイルが存在しません。");
    return 1;
  }
  
  QString saki (argv[2]);
  
  QFile::copy (moto, saki);
  
  return 0;
}

コード説明

  1. QFile::copy (moto, saki);
    第一引数のファイルを第二引数のファイルにコピーします。

実行


// Mac nad Linux
make

// Windows
nmake

// Mac 実行
./filedir.app/Contents/MacOS/filedir

// Linux 実行
./filedir

ファイルの所有者とグループ

filedir.cpp


#include <QTextStream>
#include <QFileInfo>

int main(int argc, char **argv)
{
  QTextStream out{stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  if (argc != 2)
  {
    qWarning ("使い方 filedir ファイル名");
    return 1;
  }
  
  QString filename = argv[1];
  
  QFileInfo fileinfo {filename};
  
  QString group = fileinfo.group();
  QString owner = fileinfo.owner();
  
  out << "グループ: " << group << Qt::endl;
  out << "オーナー: " << owner << Qt::endl;
  
  return 0;
}

ファイルを最後に開いた日、最後に変更した日

filedir.cpp


#include <QTextStream>
#include <QFileInfo>

int main(int argc, char **argv)
{
  QTextStream out{stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  if (argc != 2)
  {
    qWarning ("使い方 filedir ファイル名");
    return 1;
  }
  
  QString filename = argv[1];
  
  QFileInfo fileinfo {filename};
  
  QDateTime lastread = fileinfo.lastRead();
  QDateTime lastmod = fileinfo.lastModified();
  
  out << "最後に開いた日: " << lastread.toString() << Qt::endl;
  out << "最後に変更した日: " << lastmod.toString() << Qt::endl;
  
  return 0;
}

ディレクトリの操作

filedir.cpp


#include <QTextStream>
#include <QDir>

int main(void)
{
  QTextStream out{stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  QDir dir;
  
  if (dir.mkdir ("ディレ"))
  {
    out << "ディレの作成に成功しました。"  << Qt::endl;
  }
  
  dir.mkdir ("ディレ2");
  
  if (dir.exists("ディレ2"))
  {
    dir.rename("ディレ2", "DIR");
  }
  
  dir.mkpath ("TMP/DIR2");
  
  return 0;
}

コード説明

  1. dir.mkpath ("TMP/DIR2");
    引数の通りに親ディレクトリと子ディクレトリを作ってくれます。

基本的なパス

QDir にはホームディレクトリやルートディレクトリなどのシステムの基本的なパスを得るためのメソッドがあります。

filedir.cpp


#include <QTextStream>
#include <QDir>

int main(void)
{
  QTextStream out{stdout};
  
  out << "Current path:"  << QDir::currentPath() << Qt::endl;
  out << "Home path:" << QDir::homePath() << Qt::endl;
  out << "Temporary path:" << QDir::tempPath() << Qt::endl;
  out << "Root path:" << QDir::rootPath() << Qt::endl;
  
  return 0;
}

ファイルパス

ファイルはファイル名とパスによって識別されます。パスはファイル名、ベース名、サフィックスによって構成されています。

filedir.cpp


#include <QTextStream>
#include <QFileInfo>

int main(int argc, char **argv)
{
  QTextStream out {stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  if (argc != 2)
  {
    out << "使い方: filedir ファイル" << Qt::endl;
    return 1;
  }
  
  QString filename = argv[1];
  QFileInfo fileinfo {filename};
  
  QString absPath = fileinfo.absoluteFilePath();
  QString baseName = fileinfo.baseName();
  QString compBaseName = fileinfo.completeBaseName();
  QString fileName = fileinfo.fileName();
  QString suffix = fileinfo.suffix();
  QString compSuffix = fileinfo.completeSuffix();
  
  out << "絶対ファイルパス: " << absPath << Qt::endl;
  out << "ベース名: " << baseName << Qt::endl;
  out << "完全なベース名: " << compBaseName << Qt::endl;
  out << "ファイル名: " << fileName << Qt::endl;
  out << "サッフィクス: " << suffix << Qt::endl;
  out << "完全なサフィックス: " << compSuffix << Qt::endl;
  
  return 0;
}

実行と結果


// Mac 実行
./filedir.app/Contents/MacOS/filedir ~/Desktop/texteditor.app

// Mac 結果
絶対ファイルパス: /Users/yamada/Desktop/texteditor.app
ベース名: texteditor
完全なベース名: texteditor
ファイル名: texteditor.app
サッフィクス: app
完全なサフィックス: app

ファイルのパーミッション (権限、permission)

ファイルには誰がアクセスできるかの権限 (パーミッション) が決まっています。

filedir.cpp


#include <QTextStream>
#include <QFile>

int main(int argc, char **argv)
{
  QTextStream out {stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  if (argc != 2)
  {
    out << "使い方: filedir ファイル" << Qt::endl;
    return 1;
  }
  
  QString filename = argv[1];
  auto pm = QFile::permissions(filename);
  
  QString f;
  
  if (pm & QFile::ReadOwner)
    f.append('r');
  else
    f.append('-');
  if (pm & QFile::WriteOwner)
    f.append('w');
  else
    f.append('-');
  if (pm & QFile::ExeOwner)
    f.append('x');
  else
    f.append('-');
  if (pm & QFile::ReadGroup)
    f.append('r');
  else
    f.append('-');
  if (pm & QFile::WriteGroup)
    f.append('w');
  else
    f.append('-');
  if (pm &QFile::ExeGroup)
    f.append('x');
  else
    f.append('-');
  if (pm & QFile::ReadOther)
    f.append('r');
  else
    f.append('-');
  if (pm & QFile::WriteOther)
    f.append('w');
  else
    f.append('-');
  if (pm &QFile::ExeOther)
    f.append('x');
  else
    f.append('-');
  
  out << f << Qt::endl;
  
  return 0;
}

実行と結果


// Mac 実行
/filedir.app/Contents/MacOS/filedir ~/Desktop/texteditor.app

// 結果
rwxr-xr-x

ディレクトリの内容を表示する

filedir.cpp


#include <QTextStream>
#include <QFileInfo>
#include <QDir>

int main(int argc, char **argv)
{
  QTextStream out {stdout};
  
  // 次の一行はWindowsで日本語の文字化けを防ぐためのコードです。
  out.setEncoding(QStringConverter::System);
  
  if (argc != 2)
  {
    out << "使い方: filedir ディレクトリ" << Qt::endl;
    return 1;
  }
  
  QString directory = argv[1];
  QDir dir {directory};
  if (!dir.exists())
  {
    qWarning ("ディレクトリは存在しません。");
    return 1;
  }
  
  dir.setFilter(QDir::Files | QDir::AllDirs);
  dir.setSorting(QDir::Size | QDir::Reversed);
  
  QFileInfoList list = dir.entryInfoList();
  int max = 0;
  
  for (QFileInfo info: list)
  {
    QString name = info.fileName();
    int size = name.size();
    if (size > max)
      max = size;
  }
  
  int len = max + 2;
  
  out << QString("Filename").leftJustified(len).append("Bytes") << Qt::endl;
  
  for (int i = 0; i < list.size(); ++i)
  {
    QFileInfo fileinfo = list.at(i);
    QString s = fileinfo.fileName().leftJustified(len);
    s.append(QString("%1").arg(fileinfo.size()));
    out << s << Qt::endl;
  }
  
  return 0;
}

実行と結果


// Mac 実行
./filedir.app/Contents/MacOS/filedir ../filedir
もしくは
./filedir.app/Contents/MacOS/filedir .

// 結果
Filename     Bytes
filedir.app  96
.            288
..           480
filedir.pro  711
filedir.cpp  1031
filedir.o    6456
Makefile     84975

日本語などワイドバイト文字が混ざると正しく整列しません。


320 visits
Posted: Apr. 04, 2025
Update: Apr. 17, 2025

ホーム   C/C++チュートリアル   目次