Coding & Programming/C, C++

[C언어/C++] 파일 정리(청소) 프로그램(MCSweeper) : File Sweeper v 1.0-_getdrive, _findfirst, _findnext, _unlink functions example

mainCodes 2021. 5. 9. 09:01

[C언어/C++]  파일 정리(청소) 프로그램(MCSweeper) : File Sweeper v 1.0-getdrive, _findfirst, _findnext, _unlink functions example

 

안녕하세요 JollyTree입니다 (•̀ᴗ•́)و

_findfirst, _findnext, _findclose 함수 사용법에 대해 스터디하던 중에 조금이라도 의미 있는 것을 만들어 보자는 생각에 아이디어를 더하여 C, D, E 등 드라이브 내 불필요한 파일들을 자동으로 삭제하는 간단한 프로그램을 만들어 보았습니다. 제목에서도 알 수 있듯이 컴퓨터 내에 있는 .$$$, .TMP, .BAK 등의 확장자를 가지는 파일들을 자동으로 정리해 주는 프로그램입니다. 소스코드에서 삭제 대상 확장자를 지정할 수 있습니다.

 

🔗 MCSweeper(MainCodes Sweeper) 소개

 

이름 주요 기능
MCSweeper v1.0  하드디스크(HDD), SSD 내 불필요한 파일 삭제 기능
    - BAK, .TMP, .$$$, .CHK 등

 /d /D : 드라이브 선택 기능
    - 드라이브 선택이 없으면 현재 드라이브 자동 검색 기능

 /c /C : 삭제 전 삭제 확인 기능

/p /P : 삭제 전 사전 검색 및 예상 확보 용량 보기 기능

 

🔗 디스크 정리 프로그램 MCSweeper 소스코드(Source Code):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#pragma warning ( disable : 4996 )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <direct.h>
#include <io.h>
 
//상수 및 전역변수
#define MAXPATH  1024
 
int deletedCount = 0;
double deletedSize = 0;
bool question = false;
bool pretest = false;
 
//삭제할 확장자
const char* extList[] = { "$$$""bak""tmp", "swp""chk""" };
 
 
//파일 확장자 검사 함수
bool checkExt(char* filename)
{
    char buf[_MAX_PATH] = "";
    bool ret = false;
    char* ptr = NULL;
 
    const char** list = extList;
 
    ptr = strrchr(filename, '.');
    if (ptr == NULL)
        return false;
 
    strcpy(buf, ptr + 1);
    while (**list)
    {
        if (strncmp(buf, *list++3== 0)
        {
            ret = true;
            break;
        }
    }
    return ret;
}
 
//파일 삭제 함수
int deleteFile(char* fname, unsigned long size)
{
    char opt[5];
 
    printf("%s, %.2lf KB", fname, (float)size/1024);
    if (question == true)
    {
        printf(" - 삭제 할까요? (y/N)");
        gets_s(opt);
        if ( (opt[0!= 'y'&& (opt[0!= 'Y') )
            return 0;
    }
 
    printf("  --> 삭제됨\n");
 
    if (pretest == true)
    {
        deletedCount++;
        deletedSize += size;
    }
    else
    {
        if (_unlink(fname) == -1)
            printf("    파일을 삭제할 수 없습니다.\n");
        else
            deletedCount++;
    }
 
    return 0;
}
 
//디렉토리 검색 함수
int scanDir(char *buf)
{
    struct _finddata_t fileInfo;
    intptr_t hFile;
 
    char filePath[MAXPATH] = "";
    char searchPath[MAXPATH] = "";
    char fullName[MAXPATH] = "";
 
    sprintf(filePath, "%s\\", buf);
    sprintf(searchPath, "%s\\*", buf);
    if ((hFile = _findfirst(searchPath, &fileInfo)) == -1)
        return -1;
 
    do 
    {
        memset(fullName, 0sizeof(fullName));
        sprintf(fullName, "%s%s", filePath, fileInfo.name);
        if (fileInfo.attrib & _A_SUBDIR)
        {
            if ((strcmp(fileInfo.name, "."!= 0&& (strcmp(fileInfo.name, ".."!= 0))
                scanDir(fullName);
        }
        else
        {
            if (checkExt(fileInfo.name))
                deleteFile(fullName, fileInfo.size);
        }
    } while ((_findnext(hFile, &fileInfo)) == 0);
    _findclose(hFile);
 
    return 0;
}
 
//사용법 함수
void usage()
{
    printf("\r\n사용법: MCSweeper [/D] [/P] [/C]|/?]\r\n");
    printf("                /D : 드라이브 지정.\r\n");
    printf("                /P : 사전테스트 & 삭제 시  예상 확보 용량 확인.\r\n");
    printf("                /C : 삭제전 확인.\r\n");
    printf("                /? : 사용법.\r\n\r");
 
    printf("\n  예) C 드라이브 검색    : MCSweeper /Dc /p\r\n");
    printf("      D 드라이브 검색    : MCSweeper /Dd /c\r\n");
    printf("      Z 드라이브 검색    : MCSweeper /Dz\r\n");
    printf("      현재 드라이브 검색 : MCSweeper\r\n");
}
 
int main(int argc, char* argv[])
{
    char file_path[_MAX_PATH];
    char driveLetter = 0;
    int i;
 
    printf("\nMCSweeper .BAK, .TMP, .$$$, .CHK, ETC. File Sweeper Version 1.0\n");
    printf("(c) Copyright 2021 by mainCodes\n\n");
 
    if (argc <= 1)
    {
        usage();
        exit(0);
 
    }
 
    for (i = 1; i < argc; i++)
    {
        if (argv[i] != NULL)
        {
            if ((strcmp(argv[i], "/c"== 0|| (strcmp(argv[i], "/C"== 0))
                question = true;
 
            if ((strcmp(argv[i], "/p"== 0|| (strcmp(argv[i], "/P"== 0))
                pretest = true;
 
            if ((strncmp(argv[i], "/d"2== 0|| (strncmp(argv[i], "/D"2== 0))
                driveLetter = argv[i][2];
 
            if (strcmp(argv[i], "/?"== 0)
            {
                usage();
                exit(0);
            }
 
        }
    }
 
    if (!(driveLetter >= 'A' && driveLetter <= 'Z'&&
        !(driveLetter >= 'a' && driveLetter <= 'z'))
        driveLetter = _getdrive() + 'A' - 1;
 
    sprintf(file_path, "%c:", driveLetter);
    scanDir(file_path);
 
    if (deletedCount <= 0)
        printf("\n삭제된 파일이 없습니다.\n");
    else {
        printf("\n%d 개의 파일이 삭제되었습니다.\n", deletedCount);
        printf("\n%.2lf KB의 용량이 확보되었습니다.\n", (float)deletedSize/1024);
    }
 
    return 0;
}
cs

 

MCSweeper는 /c 또는 /C, /p 또는 /P, /d 또는 /D의 주요 3가지 옵션을 제공합니다. 프로그램은 명령행 파라미터를 통해 입력된 옵션을 처리한 후 재귀함수(Recursive function)인 scanDir() 함수를 이용하여 지정한 드라이브의 루트 디렉토리부터 모든 하위 디렉토리까지 불필요한 파일들을 찾아 삭제합니다. 

 

/c 또는 /C 옵션은 파일을 삭제된 사용자에게 정말 삭제할 것인지 확인을 합니다. /d 또는 /D 옵션은 검색할 드라이브를 지정할 때 사용하는 옵션으로 /d 뒤에 C, D, E, F 등의 드라이브 문자(letter)를 추가하면 됩니다. 예를 들어 C 드라이브를 검색한다면 /dC 또는 /DC 형태로 지정합니다.

 

/p 또는 /P 옵션은 실제로 파일을 삭제하지 않고 시뮬레이션을 수행합니다. "--> 삭제됨"이라고 나오지만 실제 삭제가 되지 않습니다. 이 옵션을 사용하면 예상 삭제 파일목록과 예상 확보 용량을 확인할 수 있습니다.

 

scanDir() 함수는 삭제 대상 파일을 구분하기 위해 checkExt() 함수를 사용합니다. checkExt() 함수는 삭제 대상으로 등록된 확장자를 검사하는 함수입니다.

 

const char* extList[] = { "$$$", "bak", "tmp", "umb", "swp", "chk", "", 0 };

 

만약 checkExt() 함수의 리턴 값이 true라면 삭제 대상 파일이므로 deleteFile() 함수를 이용하여 파일을 삭제합니다. deleteFile() 함수는 /p 또는 /P 옵션, /c 또는 /C 옵션 지정 플래그(question, pretest)를 확인하여 옵션에 따라 실행됩니다.

 

 

🔗 실행결과(Output):

 

 사용법 화면

 

  /dc /p 옵션 적용 화면

 

  /c 옵션 적용 화면

 

상 JollyTree였습니다. (•̀ᴗ•́)و