检测损坏dcm文件

VTK判断dcm文件是否损坏
bool IsDicomFile(string filePath)
{
    //返回值 0(no),1(yes)
    //verify it is a valid DICOM file
    bool bIsDicomFile = false;
    FILE *fp = fopen( filePath.c_str(), "r" );
    if ( fp ) {
        char signature[DCM_MagicLen];
        //#define DCM_MagicLen 4; #define DCM_PreambleLen 128 序言长度; #define SEEK_SET 0; #define DCM_Magic "DICM"
        bIsDicomFile = fseek( fp, DCM_PreambleLen, SEEK_SET ) >= 0
                && fread( signature, 1, DCM_MagicLen, fp ) == DCM_MagicLen && strncmp( signature, DCM_Magic, DCM_MagicLen ) == 0;
        fclose(fp);
    }
    return bIsDicomFile;
}

bool isDICOMbad(string process ,const string fileDir)
{
    /*功能:
     * (1)根据形参,判断一个dicom文件是否损坏
     * (2)如果传入是非dicom文件,不做判断,直接返回0
     * 返回值:0(正常文件),1(文件有损坏)
    */
    long int resultCode = 0;
    if(IsDicomFile(fileDir))
    {
        resultCode = vtkDICOMParserCode(fileDir.c_str());
        std::cout << getTimeZZ() << " [坏文件]: "<<fileDir<<" ["<<process<<"] "<<" errorCode:"<< resultCode << std::endl;
    }
    return resultCode;
}

void isDirDicomBad(const string dataDir,string process)
{
    /*
     * 功能:
     * (1)检查某个目录(递归)下(形参:dataDir)的所有文件是否损坏
     * (2)若某个文件损坏,则会自动移动到目录(BadFiledirPath)中去
    */

    //递归获取指定目录的所有文件夹名称
    QVector<QString> folderList;
    GetAllFileFolder(QString(dataDir.c_str()), folderList);
    folderList.append(QString(dataDir.c_str()));

    for(auto subFolderList:folderList)
    {
        QList<QString> list = subFolderList.split("/");//subFolderList="/data/testa/00000001/st01"和"/data/testa/00000001/"
        //以下是处理目录,使目录后面都有"/"
        QString out_file_name = "/";
        if(list.size() > 1)
        {
            for (int i = 0; i < list.size(); i++)
            {
                if(list[i].size() > 1)
                    out_file_name += list[i] + "/";
            }
        }
        else
        {
            out_file_name = subFolderList + "/";
        }
        //遍历每个目录下的所有文件进行判断
        std::vector<string> searchFileDir;
        searchFileDir.clear();
        searchFileDir = getDirFilesList(out_file_name.toStdString()); //searchFileDir[j]="/data/testa/99900001/st01/t9990000101mr.dcm"
        for(int j = 0;j < searchFileDir.size();j++)
        {
            if(isDICOMbad(process,searchFileDir[j]))
            {
                MovefiletoDirectory(searchFileDir[j],BadFiledirPath);
                continue;
            }
        }
    }
}
//vtkDICOMParser获取错误码
long int vtkDICOMParserCode(const char *fileName_str)
{
    vtkSmartPointer<vtkStringArray> files =
            vtkSmartPointer<vtkStringArray>::New();
    char fileName[128]; //the file max length
    sprintf(fileName,fileName_str, 1);
    files->InsertNextValue(fileName);
    vtkSmartPointer<vtkDICOMDirectory> sorter =
            vtkSmartPointer<vtkDICOMDirectory>::New();
    sorter->RequirePixelDataOff();
    sorter->SetScanDepth(0);
    sorter->IgnoreDicomdirOn();
    // sorter->SetFindQuery(query);
    sorter->SetInputFileNames(files);
    sorter->Update();
    vtkDICOMCharacterSet charset;
    vtkSmartPointer<vtkDICOMParser> parser =
            vtkSmartPointer<vtkDICOMParser>::New();
    parser->SetDefaultCharacterSet(charset);

    vtkSmartPointer<vtkDICOMMetaData> data =
            vtkSmartPointer<vtkDICOMMetaData>::New();
    parser->SetMetaData(data);

    int m = sorter->GetNumberOfStudies();
    for (int j = 0; j < m; j++)
    {
        int k = sorter->GetFirstSeriesForStudy(j);
        int kl = sorter->GetLastSeriesForStudy(j);
        for (; k <= kl; k++)
        {
            vtkStringArray *a = sorter->GetFileNamesForSeries(k);
            vtkIdType l = a->GetNumberOfValues();
            std::string fname = a->GetValue(0);

            // print the first and last filenames (sorted)
            vtkSmartPointer<vtkSortFileNames> fsort =
                    vtkSmartPointer<vtkSortFileNames>::New();
            fsort->NumericSortOn();
            fsort->IgnoreCaseOn();
            fsort->GroupingOff();
            fsort->SetInputFileNames(a);
            fsort->Update();

            data->Clear();
            data->SetNumberOfInstances(static_cast<int>(l));

            unsigned int pixelDataVL = 0;
            for (vtkIdType i = 0; i < l; i++)
            {
                fname = a->GetValue(i);
                parser->SetIndex(i);
                parser->SetFileName(fname.c_str());
                parser->Update();
                pixelDataVL = parser->GetPixelDataVL();
            }

        }
    }

    return parser->GetErrorCode ();
}


std::vector<string> getFileNameFromFilesList(std::vector<string> names)
{
    /*
     * 功能:从包含绝对路径的文件路径取出文件名出来
    */
    std::vector<string> fileNames;
    for(int i = 0; i < names.size(); i++)
    {
        string fileName = names[i];
        fileName = fileName.substr(fileName.find_last_of("/") + 1);
        fileNames.push_back(fileName);
    }
    return fileNames;
}

std::vector<string> getDirFilesList(string dirName)
{
    /*
     * 功能:获取制定目录下所有文件的绝对路径(不递归)
    */
    std::vector<string> vFiles;
    cout << "[getDirFilesList:]dirName= " << dirName << endl;
    DIR *pDir = opendir(dirName.c_str());//dirName= /home/nishome/lvjunrong/spmFile/PACS/Post/Pending/
    if(pDir)
    {
        struct dirent *pDirEnt = NULL;
        while(pDirEnt = readdir(pDir))
        {
            string dirEntName = pDirEnt->d_name;//dirEntName= m20200327165341dcm/m20200327165341png
            if(!IsDirectory(dirName + dirEntName))
            {
                vFiles.push_back(dirName + dirEntName);
            }
        }
        closedir(pDir);
    }
    return vFiles;
}
void GetAllFileFolder(QString dirPath, QVector<QString> &folderList)
{
    /*
     * 功能:获取文件夹下的所有文件夹绝对路径(递归)
    */
    QDir dir(dirPath);
    dir.setFilter(QDir::Dirs);
    foreach(QFileInfo fullDir, dir.entryInfoList())
    {
        if(fullDir.fileName() == "." || fullDir.fileName() == "..") continue;
        folderList.push_back(fullDir.absoluteFilePath());
        GetAllFileFolder(fullDir.absoluteFilePath(), folderList);
    }
    return ;
}

//将文件移动到目标文件夹下
void MovefiletoDirectory(const string Srcfile ,const string desPath)
{
    if (FileExists( Srcfile) && FileExists(desPath))
    {
        string mvFile = "mv  -f " + Srcfile +  "  " + desPath;
        cout << getTimeZZ() << " [移动文件]:mv " << Srcfile << " to " << desPath << endl;
        bool moveCmdResult = checkShellCm(mvFile.c_str());
        if(moveCmdResult == 0)
            cout << "移动文件:" << Srcfile << "到目录:" << desPath << "成功" <<endl;
        else
        {
            cout << "移动文件:" << Srcfile << "到目录:" << desPath << "失败" << endl;
            return;
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值