본문 바로가기

Language/Python

[Python] File Access Time 을 이용한 파일 삭제

반응형

개요

  • 사용하던 스토리지 사용량이 90%를 넘어가 정리가 필요
  • 스토리지에 저장된 파일들의 사이즈는 1Mbyte 아래로 작은편
  • 각각의 디렉토리 내에 파일들이 수만개가 존재하여 shell에서 list(ls)하는것도 시간이 많이 소요됨 

 

소스

  • 파일의 MAC time 중 access time이 1년 이상 된 파일들 만을 대상으로 삭제 진행
  • 디렉토리와 숨김 파일은 삭제 하지 않음.
  • queue와 multithread를 이용하여 producer가 파일만을 찾아 queue에 넣고 consumer가 queue에서 빼서 위 조건을 만족하는 파일을 삭제하고 로그를 남기는 구조
#!/usr/bin/python3

import os
import time
import glob
import datetime
import queue
import threading

# 재귀 함수(file_search)의 depth 증가
import sys
sys.setrecursionlimit(10**9)

# 파일 사이즈 단위 변환
def convert_size(size_bytes):
	import math
	if size_bytes == 0:
		return "0B"
	size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
	i = int(math.floor(math.log(size_bytes, 1024)))
	p = math.pow(1024, i)
	s = round(size_bytes / p, 2)
	return "%s %s" % (s, size_name[i])

# 파일을 삭제하고 로그 남김
def log_c(file,size,check,atime):
	global file_total_count
	global file_check_count
	global file_total_size
	global file_check_size
	log_time = datetime.datetime.now()
	log_path = "<log path>"
	f = open(log_path, 'a')
	file_total_count += 1
	file_total_size += size
	if check == 1:
		now = datetime.datetime.fromtimestamp(atime)
		time_atime = now.strftime('%Y-%m-%d %H:%M:%S')
		f.write("[{c}] \t [size: {a}] \t [atime: {d}] \t {b}\t".format(a=size, b=file, c=log_time, d=time_atime))
		file_check_count += 1
		file_check_size += size
		try:
			os.remove(file)
			f.write("[DELETE : SUCCESS]\n")
		except:
			f.write("[DELETED : FAIL]\n")
			sys.exit(1)
	f.write("[Total File Count : {a}/{b}]\t".format(a=file_check_count,b=file_total_count))
	f.write("[Total File size : {a}/{b}]\n".format(a=convert_size(file_check_size),b=convert_size(file_total_size)))
	f.close()

# 파일을 찾아 queue에 넣음 
def file_search(path):
	for file in glob.glob(path):
		if not file.startswith(".") and os.path.isfile(file):
			q.put(file)
		elif os.path.isdir(file):
			file_search(file+"/*")

# queue에서 파일을 빼서 access time이 1년 이상인 파일 선별
def q_get(t1):
	while True:
		if not t1.is_alive() and q.qsize() == 0:
			break
		file = q.get()
		(mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file)
		if (now_time - atime) > std_time:
			log_c(file,size,1,atime)
		else:
			log_c(file,size,0,0)

# thread를 이용하여 producer(file_search), consumer(q_get)을 띄움
def main(path):
        t1 = threading.Thread(target=file_search, args=(path,))
        t2 = threading.Thread(target=q_get, args=(t1,))
        t1.start()
        t2.start()

        t1.join()
        t2.join()

if __name__ == "__main__":
	# 기준 경로
	path = "/<path>/*"

	# 기준 시간, 1년
	std_time = 31536000

	now_time = time.time()
	file_total_count = 0
	file_total_size = 0
	file_check_count = 0
	file_check_size = 0

	q = queue.Queue()

	main(path)
반응형