「Qtの基礎 - ファイル」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
99行目: 99行目:
     QString strErrMsg = "";
     QString strErrMsg = "";
     QFileInfo FileInfo(FileName);
     QFileInfo FileInfo(FileName);
    if(FileInfo.exists())
    {
        strErrMsg = "既存ファイル(" + FileInfo.suffix() + ")には出力できません"
        QMessageBox::information(this, tr("ファイル出力エラー"), strErrMsg);
        return;
    }
   
   
     QFile File(FileName);
     QFile File(FileName);
     if (!File.open(QIODevice::WriteOnly))
     if(!File.open(QIODevice::WriteOnly))
     {
     {
       strErrMSg = "ファイル(" + FileInfo.suffix() + ")オープンエラー:" + File.errorString();
       QString strErrMsg = "File(" + FileInfo.fileName() + ") Open Error: " + File.errorString();
       qDebug() << strErrMsg;
       qDebug() << strErrMsg;
       return;
       return;
122行目: 116行目:
<br>
<br>
==== バイナリデータの書き込み ====
==== バイナリデータの書き込み ====
バイナリデータを書き込む場合は、<code>QFile</code>クラスの<code>write</code>メソッドを使用する。<br>
<br>
QDataStreamを使用してバイナリデータを書き出す場合、以下の問題が生じる。<br>
QDataStreamの仕様において、バイナリデータを書き込む場合、先頭にバイナリデータのサイズが追加される。<br>
これは、QDataStreamはバイナリデータを直列化するためのものだからである。<br>
<syntaxhighlight lang="c++">
#include <QFile>
QFile File(FileName);
if(!File.open(QIODevice::WriteOnly))
{
    QString strErrMsg = "File(" + QFileInfo(File).fileName() + ") Open Error: " + File.errorString();
    qDebug() << strErrMsg;
    return;
}
QByteArray ByAryData = QString("48656c6c6f").toUtf8().toHex();
File.write(ByAryData);
File.close();
</syntaxhighlight>
<br><br>
== INIファイル ==
以下の例では、ソフトウェアにおけるウインドウの状態を保存している。<br>
<br>
ウインドウの座標、縦横のサイズ、状態、最少幅、タイトル文字列をSetting.iniファイルに保存する。<br>
もし、Settings.iniファイルが存在する場合は上書きする。<br>
<syntaxhighlight lang="c++">
void MainWindow::saveSetting()
{
    QSettings settings("settings.ini", QSettings::IniFormat, this);
    settings.beginGroup("MainWindow");
    settings.setValue("pos", pos());
    if(!isMaximized())
    {
      settings.setValue("size", size());
    }
    settings.setValue("maximized", isMaximized());
    settings.setValue("miniwid", minimumWidth());
    settings.setValue("title", windowTitle());
    settings.endGroup();
}
</syntaxhighlight>
<br>
以下の例では、前回のウインドウの状態を復元している。<br>
Setting.iniファイルから必要な情報を読み込み、画面の状態を変更する。<br>
<br>
Settings.iniファイルが存在しない場合またはpos等のキー値が無ければ何もしない。<br>
<syntaxhighlight lang="c++">
bool MainWindow::loadSetting()
{
    QSettings settings("settings.ini", QSettings::IniFormat, this);
    settings.beginGroup("MainWindow");
    if(settings.contains("pos"))
    {
      move(settings.value("pos", QPoint(50, 40)).toPoint());
    }
    if(settings.contains("size"))
    {
      resize(settings.value("size", QSize(800, 720)).toSize());
    }
    if(settings.value("maximized").toBool())
    {
      setWindowState(windowState() | Qt::WindowMaximized);
    }
    if(settings.contains("miniwid"))
    {
      setMinimumWidth(settings.value("miniwid", 400).toInt());
    }
    if(settings.contains("title"))
    {
      setWindowTitle(settings.value("title", "なし").toString());
    }
    settings.endGroup();
}
</syntaxhighlight>
<br>
以下に、設定ファイル(Settings.ini)の内容を示す。<br>
左上位置(46, 15)、画面サイズ(800x600)、最大化(false)、最少幅(400)、画面のタイトルが"サンプル画面"の場合である。<br>
[MainWindow]
pos=@Point(46 15)
size=@Size(800 600)
maximized=false
miniwid=400
title=\x30b5\x30f3\x30d7\x30eb\x753b\x9762
<br><br>
== ファイル情報 ==
ファイルが存在すればtrue、存在しなければfalseを返す。<br>
<syntaxhighlight lang="c++">
bool MainWindow::FileExists(QString FileName)
{
    QFileInfo FileInfo(FileName);
    return FileInfo.exists();
}
</syntaxhighlight>
<br>
ファイルタイプの確認において、ファイルは1、ディレクトリは2、その他は0を返す。<br>
<syntaxhighlight lang="c++">
int MainWindow::FileType(QString FileName)
{
    QFileInfo fileInfo(FileName);
    if(FileInfo.isFile())
    {
      reuturn 1;
    }
    else if(FileInfo.isDir())
    {
      reuturn 2;
    }
    return 0;
}
</syntaxhighlight>
<br>
以下に、ファイル情報の取得例を示す。<br>
<syntaxhighlight lang="c++">
QFileInfo f1("~/memo.txt");
QFileInfo f2("~/arc.tar.gz");
QFileInfo f3("~/memo.txt_シンボリックリンク");
</syntaxhighlight>
<br><br>
== ファイルの再帰検索 ==
再帰呼び出しを使用して、サブディレクトリのファイル名まで取得する。<br>
各ディレクトリごとに再帰処理を行い、ファイルのパスをリストに追加している。<br>
<syntaxhighlight lang="c++">
QStringList MainWindow::SearchFiles(const QString &Path)
{
  QDir dir(Path);
  QStringList list;
  foreach(QString File, dir.entryList(QDir::Files))
  {
      list.append(Path + QDir::separator() + File);
  }
  foreach(QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
  {
      list = list << SearchFiles(Path + QDir::separator() + subDir);
  }
  return list;
}
</syntaxhighlight>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:Qt]]
[[カテゴリ:Qt]]

2021年1月26日 (火) 00:37時点における版

概要

ソフトウェアにおいて、ファイルの操作は非常に重要な項目である。
テキストファイルやバイナリファイル、画像ファイル等、各フォーマットにしたがって、ファイルの入出力を行う必要がある。

ファイルフォーマットは、公開・非公開のものがあり、各フォーマットを理解してファイルの入出力を行うことは難しいが、
ライブラリを使用する場合、簡単に入出力を行うことができる。


ファイルの読み込み

テキストファイルの一括読み込み

以下の例では、一括で読み込んだテキストデータを改行コードで分割して、行数分だけ回して処理している。
ファイルのオープンに失敗した場合、エラーメッセージをデバッグ出力して終了する。

 #include <QTextStream>
 #include <QFile>
 
 void MainWindow::readTextFileAll(const QString &FileName)
 {
    QFile File(FileName);
    if(!File.open(QIODevice::ReadOnly))
    {
       QString strErrMsg = "File(" + QFileInfo(File).fileName() + ") Open Error: " + File.errorString();
       qDebug << strErrMsg;
       return;
    }
 
    QTextStream InStream(&File);
    QString strTextData = InStream.readAll();
    File.close();
 
    QList<QString> Lines = istrTextData.split("\n");
    foreach (QString Line, Lines)
    {
       qDebug() << line;
       break;
    }
 }


テキストファイルの1行読み込み

以下の例では、テキストストリームから1行ずつ読み込んで処理している。
ファイルを閉じた場合、テキストストリームが使用できなくなるため、最後にファイルを閉じる。

 #include <QTextStream>
 #include <QFile>
 
 void MainWindow::readTextFileLine(const QString &FileName)
 {
    QFile File(FileName);
    if(!File.open(QIODevice::ReadOnly))
    {
       QString strErrMsg = "File(" + QFileInfo(File).fileName() + ") Open Error: " + File.errorString();
       qDebug() << strErrMsg;
       return;
    }
 
    QTextStream InStream(&File);
 
    while(!InStream.atEnd())
    {
       qDebug() << InStream.readLine();
       break;
    }
 
    File.close();
 }


バイナリデータの読み込み

バイナリデータを読み込む場合は、QFileクラスのreadLineメソッドまたはreadAllメソッドを使用する。

QDataStreamを使用してバイナリデータを書き出す場合、以下の問題が生じる。
QDataStreamの仕様において、バイナリデータを書き込む場合、先頭にバイナリデータのサイズが追加される。
これは、QDataStreamはバイナリデータを直列化するためのものだからである。

 #include <QFile>
 
 QFile File(FileName);
 if(!File.open(QIODevice::ReadOnly))
 {
    QString strErrMsg = "File(" + QFileInfo(File).fileName() + ") Open Error: " + File.errorString();
    qDebug() << strErrMsg;
    return;
 }
 
 QByteArray ByAryData = File.readAll();
  
 File.close();



ファイルの書き込み

テキストファイルの一括書き込み

以下の例では、テキストデータをファイルに出力している。
既にファイルが存在する場合は、エラーメッセージを表示して終了する。

 void MainWindow::writeTextFile(QString FileName, QString strOutputData)
 {
    QString strErrMsg = "";
    QFileInfo FileInfo(FileName);
 
    QFile File(FileName);
    if(!File.open(QIODevice::WriteOnly))
    {
       QString strErrMsg = "File(" + FileInfo.fileName() + ") Open Error: " + File.errorString();
       qDebug() << strErrMsg;
       return;
    }
 
    QTextStream OutStream(&File);
    OutStream << strOutputData;
 
    File.close();
 }


バイナリデータの書き込み

バイナリデータを書き込む場合は、QFileクラスのwriteメソッドを使用する。

QDataStreamを使用してバイナリデータを書き出す場合、以下の問題が生じる。
QDataStreamの仕様において、バイナリデータを書き込む場合、先頭にバイナリデータのサイズが追加される。
これは、QDataStreamはバイナリデータを直列化するためのものだからである。

 #include <QFile>
 
 QFile File(FileName);
 if(!File.open(QIODevice::WriteOnly))
 {
    QString strErrMsg = "File(" + QFileInfo(File).fileName() + ") Open Error: " + File.errorString();
    qDebug() << strErrMsg;
    return;
 }
 
 QByteArray ByAryData = QString("48656c6c6f").toUtf8().toHex();
 
 File.write(ByAryData);
 
 File.close();



INIファイル

以下の例では、ソフトウェアにおけるウインドウの状態を保存している。

ウインドウの座標、縦横のサイズ、状態、最少幅、タイトル文字列をSetting.iniファイルに保存する。
もし、Settings.iniファイルが存在する場合は上書きする。

 void MainWindow::saveSetting()
 {
    QSettings settings("settings.ini", QSettings::IniFormat, this);
    settings.beginGroup("MainWindow");
    settings.setValue("pos", pos());
 
    if(!isMaximized())
    {
       settings.setValue("size", size());
    }
 
    settings.setValue("maximized", isMaximized());
    settings.setValue("miniwid", minimumWidth());
    settings.setValue("title", windowTitle());
 
    settings.endGroup();
 }


以下の例では、前回のウインドウの状態を復元している。
Setting.iniファイルから必要な情報を読み込み、画面の状態を変更する。

Settings.iniファイルが存在しない場合またはpos等のキー値が無ければ何もしない。

 bool MainWindow::loadSetting()
 {
    QSettings settings("settings.ini", QSettings::IniFormat, this);
    settings.beginGroup("MainWindow");
 
    if(settings.contains("pos"))
    {
       move(settings.value("pos", QPoint(50, 40)).toPoint());
    }
 
    if(settings.contains("size"))
    {
       resize(settings.value("size", QSize(800, 720)).toSize());
    }
 
    if(settings.value("maximized").toBool())
    {
       setWindowState(windowState() | Qt::WindowMaximized);
    }
 
    if(settings.contains("miniwid"))
    {
       setMinimumWidth(settings.value("miniwid", 400).toInt());
    }
 
    if(settings.contains("title"))
    {
       setWindowTitle(settings.value("title", "なし").toString());
    }
 
    settings.endGroup();
 }


以下に、設定ファイル(Settings.ini)の内容を示す。
左上位置(46, 15)、画面サイズ(800x600)、最大化(false)、最少幅(400)、画面のタイトルが"サンプル画面"の場合である。

[MainWindow]
pos=@Point(46 15)
size=@Size(800 600)
maximized=false
miniwid=400
title=\x30b5\x30f3\x30d7\x30eb\x753b\x9762



ファイル情報

ファイルが存在すればtrue、存在しなければfalseを返す。

 bool MainWindow::FileExists(QString FileName)
 {
    QFileInfo FileInfo(FileName);
 
    return FileInfo.exists();
 }


ファイルタイプの確認において、ファイルは1、ディレクトリは2、その他は0を返す。

 int MainWindow::FileType(QString FileName)
 {
    QFileInfo fileInfo(FileName);
    if(FileInfo.isFile())
    {
       reuturn 1;
    }
    else if(FileInfo.isDir())
    {
       reuturn 2;
    }
 
    return 0;
 }


以下に、ファイル情報の取得例を示す。

 QFileInfo f1("~/memo.txt");
 QFileInfo f2("~/arc.tar.gz");
 QFileInfo f3("~/memo.txt_シンボリックリンク");



ファイルの再帰検索

再帰呼び出しを使用して、サブディレクトリのファイル名まで取得する。
各ディレクトリごとに再帰処理を行い、ファイルのパスをリストに追加している。

 QStringList MainWindow::SearchFiles(const QString &Path)
 {
   QDir dir(Path);
   QStringList list;
 
   foreach(QString File, dir.entryList(QDir::Files))
   {
      list.append(Path + QDir::separator() + File);
   }
 
   foreach(QString subDir, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot))
   {
      list = list << SearchFiles(Path + QDir::separator() + subDir);
   }
 
   return list;
 }