- 공유 링크 만들기
- X
- 이메일
- 기타 앱
이 글의 목적은 손상된 한글 HWP 파일을 가능한 범위에서 안전하게 복구하기 위한 절차를 증상별·원인별로 체계화하여 현장에서 즉시 적용할 수 있도록 돕는 것이다.
1. 손상 진단: 복구 전에 반드시 확인할 체크리스트
복구 성공률을 높이려면 파일 자체 문제와 저장 매체 문제를 분리 진단해야 한다. 아래 표의 순서대로 점검하면 된다.
| 점검 항목 | 확인 방법 | 판정/조치 |
|---|---|---|
| 매체 이상 여부 | 외장 USB/SSD/HDD라면 다른 PC에서 읽기 전용으로 마운트하고 S.M.A.R.T. 경고 유무를 확인한다. Windows는 CrystalDiskInfo 사용, Mac은 디스크 유틸리티 진단을 사용한다. | 경고가 있으면 즉시 전체 이미징 후 복구를 진행한다. |
| 파일시스템 오류 | Windows 탐색기에서 드라이브 속성 → 도구 → 오류 검사 실행 또는 chkdsk 로그 확인한다. | 오류가 있으면 먼저 이미지 백업 후 복구한다. |
| 버전/확장자 확인 | 파일 확장자가 .hwp인지 확인하고, 작성 버전을 기억한다(한컴오피스 한/글 2007, 2010, NEO 등). | 버전 불일치 시 동일 또는 상위 버전에서 열기를 시도한다. |
| 복사 가능 여부 | 원본이 있는 드라이브에서 다른 드라이브로 해시를 확인하며 복사한다. | 복사 실패 시 읽기 재시도 옵션으로 재복사한다. |
| 증상 분류 | 오류 메시지 내용을 기록한다. 예: “파일 형식이 올바르지 않다”, “손상된 문서입니다”, “열 수 없습니다”. | 아래 2장 증상별 절차로 진행한다. |
1.1 안전한 복사와 해시 검증
복구는 반드시 사본에서 진행해야 한다. 아래 명령을 사용하면 바이트 단위 동일성을 확인하며 사본을 만들 수 있다.
:: 관리자 권한 PowerShell # 1) 원본 파일 해시 Get-FileHash "D:\damaged\report.hwp" -Algorithm SHA256
2) 읽기 재시도/백업 모드로 복사
robocopy "D:\damaged" "E:\work" "report.hwp" /R:3 /W:2 /Z /COPY:DAT
3) 사본 파일 해시
Get-FileHash "E:\work\report.hwp" -Algorithm SHA256
두 해시값이 동일하면 안정적인 사본 확보 완료
2. 증상별 복구 절차
2.1 “파일 형식이 올바르지 않다” 또는 헤더 오류
HWP는 OLE Compound 구조를 사용하는 경우가 많다. 헤더가 일부 파손되면 한/글에서 열기 실패가 발생한다. 다음 순서로 텍스트·객체 스트림을 직접 추출한다.
- 7-Zip 또는 OLE 뷰어로 파일 열기를 시도한다. 내부에
FileHeader,BodyText,BinData등 스트림이 보이면 구조는 살아있을 가능성이 높다. BodyText와BinData를 내보내기 한다.BodyText/Section0,BodyText/Section1등 섹션 단위 스트림이 있으면 모두 추출한다.- 텍스트 추출 도구 또는 파이썬 스크립트로 바디 텍스트를 디코딩한다.
# Python 3.x 예시: olefile 활용 import olefile, re
def extract_hwp_text(path):
texts = []
with olefile.OleFileIO(path) as ole:
for stream in ole.listdir():
s = "/".join(stream)
if s.startswith("BodyText/Section"):
with ole.openstream(stream) as f:
data = f.read()
# 간단 추출: 가시문자 범위로 필터링
txt = re.sub(rb'[^ \t\r\n -~\x80-\xff]+', b' ', data)
texts.append(txt.decode("cp949", errors="ignore"))
return "\n".join(texts)
print(extract_hwp_text(r"E:\work\report.hwp"))
2.2 “문서가 손상되어 복구합니다” 이후 실패
한/글의 자동 복구 로직이 실패한 상황이다. 이때는 임시 저장 및 자동 저장 파일, 이전 버전 복원을 활용한다.
- 임시/자동 저장 위치에서 최근 스냅샷을 찾는다. 사용자 프로필의 로컬 AppData 또는 한컴 오피스의 임시 폴더에
*.tmp,*.bak,~$*.hwp,*.asv유사 파일이 존재할 수 있다. - 파일 크기와 수정 시간을 기준으로 후보를 선별하고 확장자를
.hwp로 변경하여 열기를 시도한다. - Windows “이전 버전” 기능, OneDrive/Google Drive/기업 문서관리시스템의 버전 기록에서 직전 정상본을 가져온다.
:: 후보 파일 일괄 복사 예시(PowerShell) $src = "$env:LOCALAPPDATA" $dst = "E:\work\autosave_dump" New-Item -ItemType Directory -Force -Path $dst | Out-Null Get-ChildItem -Path $src -Recurse -Include *.tmp,*.bak,~$*.hwp,*.asv -ErrorAction SilentlyContinue | Where-Object { $_.Length -gt 0 } | Copy-Item -Destination $dst -Force 2.3 “필요한 구성요소를 읽을 수 없습니다” 또는 바이너리 데이터 파손
문서 내 이미지·개체가 포함된 BinData 영역 파손이 의심되는 경우이다. 전략은 “텍스트 우선 구출, 개체 분리”이다.
- 7-Zip으로
BinData폴더를 제외한 항목만 새 OLE 컨테이너로 재압축 또는 추출 후 재저장한다. - 한/글에서 열리면 텍스트를 새 문서로 복사하고, 손상 이미지·개체는 재삽입한다.
2.4 확장자는 .hwp지만 실제 형식이 변조됨
네트워크 전송 오류나 잘못된 변환으로 내부가 ZIP/PDF/HTML 등 다른 포맷일 수 있다. 파일 헤더를 확인한다.
| 파일 시그니처 | 선두 바이트/문자열 | 의미 | 조치 |
|---|---|---|---|
| OLE Compound(HWP 계열) | D0 CF 11 E0 A1 B1 1A E1 | 전통 HWP 구조 | OLE 뷰어/7-Zip으로 내부 추출 |
| ZIP 컨테이너 | 50 4B 03 04 | 압축 아카이브 | 확장자를 .zip으로 바꾸고 압축 해제 |
| PDF 문서 | PDF 리더로 열기 | ||
| HTML | <!DOCTYPE html> 또는 <html> | 웹 문서 | 브라우저로 열기, 내용 복사 |
:: 헤더 미리보기(관리자 권한 PowerShell) $path = "E:\work\report.hwp" $fs = [System.IO.File]::OpenRead($path) $bytes = New-Object byte[] 16 $fs.Read($bytes,0,16) | Out-Null $fs.Close() ($bytes | ForEach-Object { $_.ToString("X2") }) -join " " 2.5 파일 크기가 0KB 또는 비정상적으로 작음
전원 장애, 미완료 동기화, 스토리지 캐시 파손 가능성이 있다. 원본 복구는 어려우나 스냅샷·버전관리·섀도 카피를 확인한다.
- Windows 파일 속성 → 이전 버전 탭에서 복원 시도한다.
- 클라우드 동기화 사용 시 웹 포털의 버전 기록에서 과거본을 내려받는다.
- 디스크 이미지에서 파일 카빙(PhotoRec 등)으로 HWP 시그니처 기반 복원을 시도한다.
3. 실무 절차: 안전 백업 → 자동/임시본 수색 → 구조적 추출 → 수동 재조립
3.1 단계 A: 포렌식 보존 사본 만들기
드라이브 전체 이미징이 최선이다. 여의치 않다면 최소한 문제 파일과 동일 폴더의 관련 임시 파일까지 일괄 보존한다.
:: 읽기 최적화 복사(에러 허용 재시도) robocopy "D:\damaged" "E:\work\case001" *.hwp *.bak *.tmp "~$*.hwp" *.asv /R:5 /W:2 /Z /COPY:DAT
:: 무결성 확인
certutil -hashfile "E:\work\case001\report.hwp" SHA256
3.2 단계 B: 자동 저장·임시본 후보 복원
아래와 같은 경로를 중심으로 후보를 수집한다. 실제 경로는 사용자·버전에 따라 달라질 수 있다.
| 유형 | 주요 위치 예시 | 파일 패턴 | 비고 |
|---|---|---|---|
| 자동 저장 | %LOCALAPPDATA%\Hancom\HOffice\Temp | *.asv, *.tmp | 확장자 변경 후 열기 시도 |
| 임시 편집본 | %TEMP% 하위 임시 폴더 | ~$*.hwp, *.tmp | 파일 크기·시간 확인 |
| 백업본 | 원본 폴더 | *.bak | 확장자 .hwp로 변경 |
| 섀도 카피 | 파일 속성 → 이전 버전 | 스냅샷 | 관리자 권한 필요 |
| 클라우드 버전 | OneDrive/Google Drive | 웹 포털 기록 | 충돌해결본 포함 확인 |
3.3 단계 C: 구조적 추출과 오류 분리
OLE 구조가 살아있다면 텍스트와 개체를 분리 추출하여 새 문서를 재조립한다.
- 텍스트 우선:
BodyText/Section*스트림에서 텍스트를 최대한 추출한다. - 개체 분리:
BinData하위 파일을 개별 저장하여 정상인 개체만 골라 재삽입한다. - 스타일 재적용: 단락 스타일·머리말·꼬리말·목차·개요번호를 새 문서에서 다시 구성한다.
3.4 단계 D: 인코딩과 깨짐 텍스트 정리
텍스트를 추출했지만 글자가 깨진다면 인코딩을 점검한다. 오래된 HWP는 CP949 계열을 사용하는 경우가 있다.
# 파이썬 간이 인코딩 정규화 raw = open("section0.bin","rb").read() for enc in ["cp949","euc-kr","utf-8","utf-16-le","utf-16-be"]: try: print(enc, raw.decode(enc)[:400]) except: pass 4. 오류 메시지별 원인·대응 매핑
| 오류 메시지(대표) | 가능 원인 | 즉시 대응 |
|---|---|---|
| 파일 형식이 올바르지 않다 | 헤더 파손, 확장자-포맷 불일치, 전송 중 변조 | 헤더 시그니처 확인, OLE/ZIP 판별 후 내부 추출 |
| 문서가 손상되어 복구합니다 → 실패 | 본문 스트림 일부 손상, 개체 영역 오류 | 자동/임시본 우선 탐색, BodyText만 추출하여 재조립 |
| 필요한 구성요소를 읽을 수 없습니다 | BinData 손상, 외부 개체 링크 끊김 | 개체 제거 모드로 열기, 텍스트 우선 복구 |
| 액세스가 거부되었습니다 | 권한·락 파일(~$) 잔존, 보안 소프트웨어 충돌 | 모든 한/글 프로세스 종료, 임시 락 파일 삭제 후 재시도 |
| 0KB 파일 | 동기화 충돌, 비정상 종료, 덮어쓰기 사고 | 이전 버전/섀도 카피/클라우드 버전 기록 복원 |
5. 개체·그림·표가 많은 문서의 특수 복구
5.1 이미지 손상 분리
이미지 손상으로 전체 열기가 막히는 경우가 있다. 아래 절차로 개체를 분리한다.
- 7-Zip으로 파일을 열고
BinData폴더만 다른 위치로 추출한다. - 문서를 열 때 개체 자동 로드를 제한하는 옵션을 적용한다(가능한 경우).
- 열기에 성공하면 텍스트를 전부 새 문서로 복사하고, 개체는 정상 파일만 재삽입한다.
5.2 표·수식 재생성 전략
- 텍스트 추출본의 표 구조는 무너질 수 있다. 중요 표는 CSV로 재작성하여 한/글 표로 재구성한다.
- 수식은 이미지로 저장되어 있을 수 있다. 원본 수식 파일이 없으면 재입력한다.
6. 데이터 손실 최소화를 위한 운영 수칙
6.1 저장·백업 정책
- 버전 분기 저장: 주요 편집 단계마다
파일명_YYYYMMDD_hhmm.hwp형식으로 새로 저장한다. - 3-2-1 규칙: 작업본 3개, 다른 매체 2개, 오프사이트 1개를 유지한다.
- 자동 저장 주기 단축: 1~3분 단위로 설정한다.
6.2 동기화 충돌 회피
- 클라우드 동기화 폴더에서 직접 편집하지 않는다. 로컬 작업 폴더에서 편집 후 종료 시 점프 복사한다.
- 동시에 두 대 이상에서 같은 파일을 열지 않는다.
6.3 전원 장애 대비
- 노트북은 배터리 상태를 주기적으로 점검한다.
- 데스크톱은 소형 UPS를 사용한다.
7. 현장 복구 체크리스트(프린트용)
| # | 항목 | 결과/메모 |
|---|---|---|
| 1 | 원본 드라이브 S.M.A.R.T. 점검 | |
| 2 | 사본 생성 및 해시 검증 | |
| 3 | 임시/자동 저장/백업본 수집 | |
| 4 | 헤더 시그니처 판별(OLE/ZIP/PDF) | |
| 5 | BodyText 스트림 텍스트 추출 | |
| 6 | BinData 분리 및 정상 개체만 재삽입 | |
| 7 | 인코딩 확인 및 깨짐 보정 | |
| 8 | 스타일·목차·번호 재구성 | |
| 9 | 최종 문서 새 이름으로 저장 |
8. 복구 품질 검증과 교차 확인
- 단락 수·페이지 수 비교: 손상 전 출력물 또는 PDF가 있으면 단락·페이지 수를 대조한다.
- 표/그림 캡션 일련번호: 누락·중복 여부를 확인한다.
- 참조·각주: 상호 참조 링크가 끊겼는지 확인한다.
9. 실패 시 선택지와 한계
- 부분 복구: 텍스트만 확보하고 서식·개체는 재작성한다.
- 이미지 우선: 연구데이터·서명 스캔 등 이미지가 핵심이면
BinData만 우선 복구한다. - 포렌식 전문 복구: 물리 매체 손상·대량 삭제·RAID 장애 등은 이미지 획득 후 전문 업체에 의뢰한다.
10. 자주 쓰는 명령어 모음
:: 파일 해시 certutil -hashfile "E:\work\report.hwp" SHA256
:: 견고 복사(재시도/중단 재개)
robocopy "D:\damaged" "E:\work" "report.hwp" /R:5 /W:2 /Z /COPY:DAT
:: 헤더 64바이트 확인(헥스)
powershell -command ^
"$b=[IO.File]::ReadAllBytes('E:\work\report.hwp');" ^
"$b[0..63] | % { $_.ToString('X2') } -join ' '"
파이썬: OLE 스트림 나열
import olefile
ole = olefile.OleFileIO(r"E:\work\report.hwp")
for s in ole.listdir():
print("/".join(s))
ole.close()
FAQ
Q1. 한/글에서 제공하는 자동 복구 기능만으로 충분한가?
자동 복구는 경미한 손상에서 효과가 있으나 스트림 파손·개체 손상에는 실패할 수 있다. 자동/임시본 확인과 OLE 내부 추출을 병행해야 한다.
Q2. 텍스트는 살렸지만 서식이 전부 무너졌다. 정상인가?
텍스트 우선 복구의 일반적 결과이다. 단락 스타일·목차·각주·캡션은 재작성한다. 핵심 데이터의 보존이 1순위이며 서식은 2순위이다.
Q3. 파일 크기가 0KB인데 복구 가능성이 있는가?
원본 파일 자체는 어렵다. 다만 이전 버전, 클라우드 버전 기록, 섀도 카피, 임시 파일에서 과거본 복원 가능성이 있다.
Q4. 이미지·차트만 따로 추출할 수 있는가?
BinData 하위 항목을 개별 파일로 저장하면 일부 포맷의 이미지는 그대로 열 수 있다. 손상된 개체는 재삽입이 필요하다.
Q5. 향후 동일 사고를 줄이려면 무엇을 바꿔야 하나?
작업 폴더 분리, 자동 저장 주기 1~3분, 버전 분기 저장, 3-2-1 백업, 클라우드와 동시 편집 금지, 소형 UPS 도입을 권장한다.