1 module caLib_util.tempdir; 2 3 import std.file : tempDir, mkdirRecurse, rmdirRecurse, exists, dirEntries, SpanMode, FileException; 4 import std.random : uniform; 5 import std.conv : to; 6 import std.path : buildNormalizedPath; 7 import std.exception : enforce; 8 9 10 private immutable string tempDirsRoot; 11 12 shared static this() 13 { 14 if(tempDir() == ".") 15 // if tempdir() returns "." it means that a temporary files root 16 // could not be found. If this happens, we make on on our own 17 tempDirsRoot = makeTempDirsRoot(); 18 else 19 tempDirsRoot = tempDir(); 20 21 // If there is any temporary files this program left behind before 22 // (this could happen if the program crashed). Remove them 23 removeTempFiles(); 24 } 25 26 shared static ~this() 27 { 28 // Remove all the temporary files we created before exiting the program 29 removeTempFiles(); 30 } 31 32 33 34 /** 35 * Creates and return a path to a private, temporary directory 36 * 37 * This function can be used when data needs to be writen to and 38 * manipulated on the disk without worring about it being overwritten by other 39 * programs or the user. This directory will be destroyed when the program 40 * exits. 41 * 42 * Returns: 43 * A path to a newly created temporary directory 44 */ 45 string makePrivateTempDir() { return makePrivateTempDir(0); } 46 47 private string makePrivateTempDir(int n) 48 { 49 // we will only try to make a temporary directory 1000 times 50 enforce(n < 1000, 51 "Could not create a temporary directory"); 52 53 // path to the new temporary directory 54 string dir = buildNormalizedPath(tempDirsRoot, "caLib3_", 55 to!string(uniform(1000, 9999))); 56 57 // if there already exists a directory in ths location 58 //redo the entire proccess 59 if(exists(dir)) 60 return makePrivateTempDir(n+1); 61 62 // otherwise, make the directory and return the path to it 63 mkdirRecurse(dir); 64 return dir; 65 } 66 67 68 69 private void removeTempFiles() 70 { 71 // if the temporary root directory is gone (it really shoulden't but its 72 // not our responibility), all the temporary files created by uss are gone. 73 // Just return 74 if(!exists(tempDirsRoot)) 75 return; 76 77 // list all the directories in the temporary files root 78 auto dirs = dirEntries(tempDirsRoot, SpanMode.shallow); 79 80 // iterate over the entries 81 foreach(dirPath ; dirs) 82 { 83 string dirName = dirPath[tempDirsRoot.length .. dirPath.length]; 84 85 // if there is a entry starting with "caLib3_" -> 86 // It was created by us -> remove the direcory 87 if(dirName.length >= 7 && dirName[0 .. 7] == "caLib3_") 88 rmdirRecurse(dirPath); 89 } 90 } 91 92 93 94 private string makeTempDirsRoot() 95 { 96 assert(0, "Can't create temporary file:" ~ 97 "This os has no location for temporary files"); 98 }