Употреба по не-предназначение - folder changes watcher с Mathematica
Във всекидневната си работа с компютър хората често се сблъскват с задачи, за които нямат предоставена автоматизация, и в много случаи е по-лесно сами да ги автоматизират отколкото да изпълняват многократно една и съща операция. И с подходящия инструмент създаването на автоматизиращо решение е доста просто.
Пиша тази тема, защото много от хората, които са запознати (дори поне малко) с Mathematica, я използват като система за извършване на символни изчисления и анализ. Но в програмата са включени и много други интересни и полезни функции, които са документирани така, че да не се налага на клиента да ги пише наново и да прекарва времето си в "детективска" работа (както се случва например с MSDN).
Със вградената си мощна пъддръжка на манипулация на низове и работа с директории и всякакъв вид файлове, Mathematica е идеална за създаването на малки скриптове за справяне със всекидневни проблеми.
Този път ще направим скрипт, чрез който се следи за промяна на някои файлове в определена директория.
Първо искаме да зададем директорията и файлът за запис на информацията:
projectDirectory="C:\\project\\";
projectHashSave="project.mx";
Сега да прочетем файловете във дадената директория, и във поддиректориите:
GetFilenames[] := Pick[#, StringMatchQ[#, __ ~~ "." ~~ __]] & /@ \
FileNames[__, {projectDirectory}, Infinity];
Използваме Pick[] за да изберем само файловете, без самите директории.
Следващата стъпка е да хешираме файловете и да ги запишем в... Всъщност Mathematica използва нещо, което може да се оприличи на hash_map. Също така Mathematica си има готова функция за хеширане на файл (отделно от функцията за хеширане на всичко друго):
projectHash[file_] := 0;
(projectHash[#] = FileHash[#]) & /@ projectFiles;
DumpSave[projectHashSave, projectHash];
projectUpdate[] := (
projectFiles = GetFilenames[];
projectHash[file_] := 0;
(projectHash[#] = FileHash[#]) & /@ projectFiles;
DumpSave[projectHashSave, projectHash];
);
За проверка кои файлове са променени, просто за всеки файл в дървото на директорията, сравняваме хеш-стойността му със записаната преди:
projectChanges[] := (
<< "project.mx";
TprojectFiles = GetFilenames[];
Print["Changed Files:"];
If[FileHash[#] != projectHash[#], Print[#]] & /@ TprojectFiles;
);
Ето скрипта в действие:
Материали: project.nb
