시작하기
FastFind 로 무엇을 만들 수 있나요?
FastFind 는 내 PC 안에 작은 검색 서버를 띄울 수 있습니다. 그래서 다른 프로그램이 검색 결과를 받아 갈 수 있습니다.
0.81 부터 웹 접속은 기본 꺼짐입니다. 설정 → 웹 접속에서 켜야 아래 REST API 가 열립니다. 켜지 않고 붙는 길도 있습니다 — 명명된 파이프 를 보십시오.
- 파워셸·파이썬 스크립트에서 파일 목록 받아오기
- 자기가 만든 런처·도구에 검색 붙이기
- 결과 우클릭 메뉴에 내 기능 끼워 넣기 (플러그인)
색인은 내 PC 안에만 있고 밖으로 나가지 않습니다. 서버도 127.0.0.1 에만 답합니다.
서버는 어디에 떠 있나요?
기본 9090 번입니다. 설정에서 바꾸실 수 있습니다.
다만 웹 접속을 켜야 열립니다. 꺼져 있으면 프로그램이 돌고 있어도 그 포트는 없습니다 — 듣는 소켓을 아예 만들지 않기 때문입니다.
중복 파일도 API 로 찾을 수 있나요?
됩니다. q 에 그대로 넣으시면 됩니다 — 검색창에 치는 것과 같은 문법입니다.
GET /api/search?q=dupe:내용 ext:jpg
GET /api/search?q=dupe: path:D:\사진
GET /api/search?q=empty:
결과는 같은 것끼리 나란히 옵니다. 덩어리 차례는 늘 같으므로, 같은 질의를 두 번 보내도 순서가 뒤바뀌지 않습니다.
dupe:내용 은 파일을 실제로 읽으므로 다른 질의보다 오래 걸립니다. 후보가 2만 개를 넘으면 내용까지는 비교하지 않고 error 에 안내를 담아 돌려줍니다 — 결과가 전부인 줄 알고 지우면 안 되기 때문입니다.
http://127.0.0.1:9090
프로그램이 꺼져 있으면 서버도 없습니다. 먼저 떠 있는지 /api/status 로 확인하고 쓰시는 편이 안전합니다.
실제로 이렇게 만든 것이 있습니다
둘 다 명명된 파이프로 붙습니다. 웹 접속을 켜지 않아도 되고, 포트도 열지 않습니다.
브라우저 시작 페이지에서 내 PC 파일을 바로 찾습니다. 웹 검색과 로컬 파일을 한 자리에서 봅니다.
검색어를 친다
/api/search
브라우저가 FastFind 를 직접 부르지 않습니다. 웹 화면에 붙는 길이 열리면 아무 사이트나 내 파일 목록을 긁어 갈 수 있으니, 믿을 수 있는 에이전트가 가운데에서 읽기만 넘겨 줍니다.
파이프가 없으면(0.81 이하 옛 판) 127.0.0.1:9090 으로 되돌아가고, 그것도 없으면 503 fastfind_not_running 으로 설치 안내를 띄웁니다. 쓰시는 분은 FastFind 를 설치·실행만 하면 됩니다.
가벼운 윈도우 사진 뷰어입니다. 그림을 보다가 PC 안의 사진을 통째로 찾는 부분을 FastFind 로 만들었습니다.
/api/search
프로그램끼리 곧장 붙으므로 가운데를 둘 일이 없습니다. 파이프 연결까지 더해 한 번 묻는 데 4~14ms 라고 알려 주셨습니다(결과 600건 기준).
이렇게 만드실 때 두 가지만 챙기시면 됩니다 — 낱말 하나만 보내면 갈래로 짐작하지 않으므로 문장을 보내실 때는 raw=1 을 붙이시고, 231 과 2 는 둘 다 다시 시도하십시오. 자세한 것은 파이프로 붙기 에 있습니다.
인증
토큰이 필요합니다
아무나 내 파일 목록을 긁어 갈 수 있으면 안 되므로, 토큰 없이는 답하지 않습니다.
두 가지 방법 중 하나로 보내십시오.
Authorization: Bearer <토큰> | 머리말에 담아 보내기 |
ff_local_token=<토큰> | 쿠키로 보내기 (브라우저에서 쓸 때) |
토큰은 /login 화면에서 받습니다. 이 두 주소만 토큰 없이 열립니다.
POST /api/local-auth/login
REST API
검색 — GET /api/search
curl -H "Authorization: Bearer $TOKEN" \
"http://127.0.0.1:9090/api/search?q=견적서%20ext:pdf&max=50"
보낼 것
q | 검색어. 사용법의 검색 문법 을 그대로 씁니다 (ext: size: path: 초성 …) |
max | 최대 몇 개까지 (생략하면 기본값) |
name_only | true 면 이름에서만, false 면 전체 경로에서 |
case | 대소문자 구분 |
word | 낱말 단위로 |
regex | 정규식으로 |
sort asc | 정렬 기준과 방향 |
raw | 친 글자 그대로만 찾습니다. 우리말 짐작을 끕니다 — 아래를 보십시오 |
참·거짓 값은 1 0 true false on off yes no 를 다 받습니다. 값을 안 적은 &raw 도 켜는 것으로 봅니다.
ext: 쓰는 법
ext:jpg,png | 쉼표로 여럿 — 이렇게 쓰십시오 |
ext:jpg|png | 안 됩니다. jpg|png 라는 확장자 하나로 읽어 0건이 됩니다 |
ext:jpg ext:png | 두 번 적으면 뒤엣것만 남습니다 |
⚠ 프로그램에서 부르실 때는 raw=1 을 붙이십시오.
기본값으로는 몇몇 낱말을 사람이 쓰기 편하게 알아듣습니다. 사람에게는 좋지만, 프로그램이 부를 때는 예고 없이 질의가 바뀌는 것이라 결과가 엉뚱해 보입니다.
다만 낱말 하나만 보내시면 갈래로 짐작하지 않습니다. q=photo 는 이름에 photo 가 든 파일을 찾습니다. 아래 표는 낱말이 둘 이상일 때(예: photo 찾아줘) 적용됩니다.
photo image 이미지 사진 그림 | → 이미지 확장자 전부 (낱말은 사라집니다) |
doc document 문서 | → 문서 확장자 전부 |
audio music 음악 오디오 | → 소리 확장자 전부 |
video 동영상 영화 영상 | → 영상 확장자 전부 |
엑셀 표 | → xls,xlsx,csv |
큰 작은 대용량 | → 크기 조건 |
10개 상위5 | → 개수 제한 |
크기순 최신순 가나다순 | → 정렬 |
폴더 파일만 | → 갈래 거르기 |
GET /api/search?q=photo → 이름에 photo 가 든 파일 (낱말 하나 — 짐작 안 함)
GET /api/search?q=photo 찾아줘 → 이미지 파일 전부 (낱말 둘 — 짐작함)
GET /api/search?q=photo 찾아줘&raw=1 → 이름에 photo 가 든 파일
ext: path: size: 같은 문법은 raw=1 을 켜도 그대로 듣습니다. 그것은 짐작이 아니라 적으신 그대로이기 때문입니다. 끄는 것은 짐작뿐입니다.
무엇으로 알아들었는지는 응답에 담겨 옵니다.
"interpreted": {
"keyword": null, // 실제로 찾은 낱말 (짐작으로 사라지면 null)
"extensions": ["jpg","png", …], // 걸린 확장자
"guessed": true, // ← 참이면 짐작이 낱말을 삼킨 것입니다
"guessed_words": ["photo"], // 무엇 때문에 바뀌었는지
"raw": false
}
guessed 가 true 면 raw=1 로 다시 부르시면 됩니다.
받을 것
{
"results": [
{
"name": "견적서_한빛건설.pdf",
"path": "C:\\작업\\2026\\견적서_한빛건설.pdf",
"size": 284915,
"ext": "pdf",
"modified": 1786012800,
"is_dir": false
}
],
"total": 12,
"time_ms": 5.3,
"query": "견적서 ext:pdf"
}
total 은 조건에 맞는 전체 개수이고 results 는 그중 돌려준 만큼입니다. modified 는 1970년부터의 초입니다.
상태 — GET /api/status
색인이 준비됐는지, 몇 개나 담고 있는지 봅니다. 검색을 보내기 전에 이걸 먼저 확인하시면 프로그램이 꺼져 있거나 아직 색인 중일 때를 가려낼 수 있습니다.
{
"indexed_files": 4663246,
"version": "0.86.0",
"status": "ready"
}
응답에 engine engine_gen mem 같은 칸도 함께 오는데, 그건 저희가 문제를 찾을 때 쓰는 값이라 예고 없이 바뀝니다. 기대지 마십시오.
자동 완성 — GET /api/suggest
치는 중에 보여 줄 후보를 받습니다. 글자 배열 하나만 돌려줍니다.
GET /api/suggest?q=견적
["견적서_한빛건설.pdf", "견적서_양식.hwp", "견적_2026.xlsx"]
파워셸에서 쓰는 짧은 보기
$t = "여기에 토큰"
$r = Invoke-RestMethod -Uri "http://127.0.0.1:9090/api/search?q=ext:log" `
-Headers @{ Authorization = "Bearer $t" }
$r.results | Select-Object name, path, size | Format-Table
파이썬에서 쓰는 짧은 보기
import requests, urllib.parse
TOKEN = "여기에 토큰"
q = urllib.parse.quote("견적서 ext:pdf")
r = requests.get(f"http://127.0.0.1:9090/api/search?q={q}&max=20",
headers={"Authorization": f"Bearer {TOKEN}"})
for f in r.json()["results"]:
print(f["size"], f["path"])
그 밖의 경로 — 있지만 약속하지 않습니다
아래도 열려 있습니다. 다만 저희 웹 화면이 쓰려고 만든 것이라 예고 없이 바뀝니다. 쓰시더라도 깨질 수 있다는 것을 알고 쓰십시오.
GET /api/recent | 최근 만들어지거나 고쳐진 파일 |
GET /api/open?path=… | 그 파일을 엽니다 |
GET /api/open-folder?path=… | 그 파일이 있는 폴더를 엽니다 |
GET /api/preview?path=… | 미리보기 그림 (이미지로 돌려줍니다) |
GET /api/analysis | 어디가 용량을 많이 쓰는지 |
GET /api/browse?path=… | 폴더 안 목록 |
/api/favorites /add /remove | 즐겨찾기 |
/api/smart-folders /add /remove /search | 저장된 검색 |
/api/history /clear | 검색 기록 |
이 중 자주 쓰시는 것이 있으면 알려 주십시오. 쓰는 분이 있는 것부터 약속 목록으로 옮기겠습니다.
실패했을 때
| 연결 거부 | 웹 접속이 꺼져 있습니다(기본값). 또는 프로그램이 꺼져 있거나 포트가 다릅니다 |
401 | 토큰이 없거나 틀렸습니다 |
404 | 없는 경로입니다 |
프로그램은 사용자가 끄면 함께 사라지고, 웹 접속을 켜지 않으면 애초에 뜨지도 않습니다. 항상 떠 있다고 여기지 마십시오. 부르기 전에 /api/status 로 확인하고, 안 되면 조용히 넘어가도록 만드시는 편이 안전합니다.
사용자에게 「설정에서 켜 주십시오」라고 부탁하고 싶지 않다면 명명된 파이프 를 쓰십시오. 웹 접속과 무관하게 늘 열려 있습니다.
포트를 어떻게 아나요?
기본은 9090 이지만 사용자가 설정에서 바꿀 수 있습니다. 배포하실 도구라면 포트를 물어보거나 설정할 수 있게 만들어 두십시오.
설정 파일에서 읽으실 수도 있습니다.
%LOCALAPPDATA%\FastFind\settings.json
판 번호는 어디에 있나요
/api/status 안에 있습니다. /api/version · /api/health · /api/info 는 없습니다(404).
기능을 쓸 수 있는지 가리실 때는 /api/status 의 version 을 보십시오.
검색에 안 나오는 곳이 있습니다
기본으로 담지 않는 폴더가 있습니다. 임시 파일과 시스템 폴더라, 담으면 결과만 어지럽고 색인도 커집니다.
| 시스템 | $Recycle.Bin · System Volume Information · Recovery |
| 윈도우 | Windows\WinSxS · Installer · servicing · Temp · Prefetch · SoftwareDistribution |
| 설치 흔적 | $WINDOWS.~BT · $WINDOWS.~WS · ProgramData\Microsoft |
| 사용자 | AppData\Local\Temp · .cache · node_modules · .git · __pycache__ |
확장자도 tmp · temp · bak · old · lnk · url 은 담지 않습니다.
쓰시는 분이 설정 → 색인 범위 에서 이 목록을 고칠 수 있으므로, 기계마다 다를 수 있습니다.
파이프로 붙기
웹 접속을 켜지 않고 붙는 방법
0.81 부터 웹 접속은 기본 꺼짐입니다. 그래서 REST API 를 쓰려면 사용자에게 설정을 켜 달라고 부탁해야 하는데, 그건 좋은 부탁이 아닙니다.
대신 명명된 파이프가 있습니다. 웹 접속과 무관하게 늘 열려 있고, 포트를 열지 않습니다.
\\.\pipe\FastFind
파이프 위에 같은 REST 라우터가 그대로 얹혀 있습니다. 그러니 경로도 파라미터도 응답도 위에서 설명한 것과 똑같습니다. 바뀌는 것은 통로뿐입니다 — 파이프에 HTTP 요청을 써 넣고 응답을 읽으면 됩니다.
어떻게 부르나
윈도우에서는 파이프를 그냥 파일처럼 열면 됩니다. 특별한 라이브러리가 필요 없습니다.
GET /api/search?q=견적서 HTTP/1.1
Host: 127.0.0.1
Connection: close
Host 는 반드시 숫자 주소여야 합니다. 이름을 적으면 거절합니다(DNS 리바인딩을 막기 위해서입니다). 값을 바꾸는 요청이라면 Sec-Fetch-Site: same-origin 도 붙이십시오. 읽기만 하는 요청에는 필요 없습니다.
Connection: close 를 빠뜨리지 마십시오. 없으면 연결이 유지되어, 끝까지 읽으려는 쪽이 영영 기다립니다. 「안 된다」가 아니라 「멈춘다」로 나타나서 찾기 어렵습니다.
다시 시도해야 하는 두 가지 오류
파이프는 인스턴스 하나에 연결 하나입니다. 여러 개를 미리 열어 두지만, 요청이 몰리면 잠깐 모자랄 수 있습니다.
231 ERROR_PIPE_BUSY | 다 차 있습니다. 잠깐 뒤 다시 |
2 ERROR_FILE_NOT_FOUND | 넘기는 찰나입니다. 이것도 다시 시도해야 합니다 |
2 번은 흔히 「없다」로 읽고 포기하게 되는데, 여기서는 「잠깐 기다리라」는 뜻일 때가 많습니다. 둘 다 짧게 몇 번 다시 시도하십시오(10ms 씩 다섯 번이면 넉넉합니다). 그러고도 2 가 계속 나오면 그때가 진짜 「FastFind 가 없다」입니다.
누가 붙을 수 있나
이 PC 에 지금 로그인한 그 사용자만 붙을 수 있습니다. 같은 PC 의 다른 계정도, 네트워크 너머도 안 됩니다.
아이디나 비밀번호를 넣을 것이 없습니다 — 윈도우가 붙은 쪽이 누구인지 알려 주므로, 우리는 파이프를 만들 때 「이 사용자만」이라고 한 번 적어 둘 뿐입니다.
플러그인
플러그인은 어떻게 동작하나요?
검색 결과를 오른쪽 클릭했을 때 나오는 메뉴에 내 기능을 끼워 넣는 것입니다.
플러그인은 별도 실행파일입니다. DLL 로 앱 안에 넣지 않습니다 — 남이 만든 코드가 잘못돼도 FastFind 가 같이 죽으면 안 되기 때문입니다. 그래서 어떤 언어로든 만드실 수 있습니다.
FastFind → 플러그인 : myplugin.exe --path "C:\\file.txt"
플러그인 → FastFind : 표준출력으로 JSON 한 덩어리
돌려줄 수 있는 것
message | 알림창을 띄웁니다 |
copy | 클립보드에 담습니다 |
open | 그 경로를 엽니다 |
{"action":"message","title":"줄 수","text":"1,284줄"}
{"action":"copy","text":"복사할 내용"}
{"action":"open","path":"C:\\어딘가"}
가장 짧은 플러그인 — 파이썬 다섯 줄
고른 파일이 몇 줄인지 세어 알려 주는 것입니다.
import sys, json
path = sys.argv[sys.argv.index("--path") + 1]
n = sum(1 for _ in open(path, encoding="utf-8", errors="ignore"))
print(json.dumps({"action": "message", "title": "줄 수",
"text": f"{n:,}줄"}, ensure_ascii=False))
이것을 exe 로 만들어 아래 자리에 넣고, 옆에 plugin.json 을 둡니다.
%LOCALAPPDATA%\\FastFind\\plugins\\linecount\\
run.exe
plugin.json
{
"id": "linecount",
"name": "줄 수 세기",
"description": "고른 파일의 줄 수를 셉니다",
"version": "1.0.0",
"author": "내 이름"
}
FastFind 를 다시 켜면 결과 우클릭 메뉴에 줄 수 세기 가 나옵니다.
이미 딸려 있는 것들
넷이 함께 설치됩니다. 만들 때 참고하십시오.
- 파일 정보 — 크기·시각·속성
- 해시 — SHA-256 계산
- 이미지 정보 — 크기·형식
- 글자 통계 — 줄·낱말·글자 수
약속과 한계
어디까지 안 바뀐다고 약속하나요?
정직하게 적겠습니다. 이 페이지에 적은 것만 약속합니다.
/api/search | 약속합니다. 칸을 빼거나 뜻을 바꾸지 않습니다 |
/api/status | indexed_files version status 세 칸만 약속합니다 |
/api/suggest | 약속합니다 |
| 플러그인 규약 | 약속합니다 |
| 그 밖의 경로 | 내부용입니다. 예고 없이 바뀝니다 |
프로그램 안에는 이보다 많은 경로가 있지만 대부분 저희 웹 화면이 쓰는 것들입니다. 공개하면 함부로 못 고치는 약속이 되므로, 안정된 것만 골라 여기 적었습니다.
새 칸이 늘어나는 일은 있습니다. 그건 기존 것을 깨지 않으니, 모르는 칸이 오면 그냥 무시하도록 만들어 두십시오.
지금은 없는 것
- 공식 라이브러리가 없습니다. HTTP 로 직접 부르셔야 합니다
- 변화 알림(웹훅)이 없습니다. 파일이 생겼을 때 알려 주는 길이 없어, 필요하면 되물어 보셔야 합니다
- 플러그인이 결과 목록을 바꿀 수는 없습니다. 지금은 우클릭 메뉴에서 한 가지 일을 하는 것까지입니다
필요하신 것이 있으면 알려 주십시오. 쓰시는 분이 있으면 만듭니다.