Directory Management
Version Compatibility: XyPriss v6.0.0 and above
Overview
The Directory Management API provides comprehensive methods for creating, listing, and managing directories. All operations handle nested directories automatically and include safety checks.
API Reference
$mkdir(path: string): void
Creates a directory and all parent directories.
Parameters:
path- Directory path to create
Examples:
// Create single directory
__sys__.$mkdir("logs");
// Create nested directories
__sys__.$mkdir("src/components/ui");
// Absolute path
__sys__.$mkdir("/var/app/data");
Behavior:
- Creates all parent directories automatically (recursive)
- No error if directory already exists
- Equivalent to
mkdir -pon Unix
$ensureDir(path: string): void
Alias for $mkdir. Ensures directory exists.
Parameters:
path- Directory path
Examples:
// Ensure directory exists before writing
__sys__.$ensureDir("output");
__sys__.$write("output/file.txt", "data");
// Ensure nested structure
__sys__.$ensureDir("cache/images/thumbnails");
Use Cases:
- Preparing output directories
- Ensuring cache directories exist
- Safe directory creation
$ls(path: string): string[]
Lists directory contents (names only).
Parameters:
path- Directory path to list
Returns: Array of file/directory names
Examples:
const files = __sys__.$ls("src");
console.log(files);
// ["index.ts", "utils.ts", "components"]
files.forEach((file) => {
console.log(file);
});
Note: Returns names only, not full paths. Use $lsFullPath() for full paths.
$lsFullPath(path: string): string[]
Lists directory contents with full paths.
Parameters:
path- Directory path to list
Returns: Array of full file/directory paths
Examples:
const paths = __sys__.$lsFullPath("src");
console.log(paths);
// ["/project/src/index.ts", "/project/src/utils.ts", "/project/src/components"]
paths.forEach((path) => {
if (__sys__.$isFile(path)) {
console.log(`File: ${path}`);
}
});
Use Cases:
- Processing files with full paths
- Recursive operations
- Path-based filtering
$lsDirs(path: string): string[]
Lists only subdirectories.
Parameters:
path- Directory path to list
Returns: Array of directory names
Examples:
const dirs = __sys__.$lsDirs("src");
console.log(dirs);
// ["components", "utils", "services"]
// Process each subdirectory
dirs.forEach((dir) => {
const fullPath = __sys__.$join("src", dir);
console.log(`Directory: ${fullPath}`);
});
Use Cases:
- Finding subdirectories
- Directory tree navigation
- Module discovery
$lsFiles(path: string): string[]
Lists only files (excludes directories).
Parameters:
path- Directory path to list
Returns: Array of file names
Examples:
const files = __sys__.$lsFiles("src");
console.log(files);
// ["index.ts", "app.ts", "config.ts"]
// Process only files
files.forEach((file) => {
const content = __sys__.$read(__sys__.$join("src", file));
processFile(content);
});
Use Cases:
- File-only processing
- Excluding subdirectories
- File counting
$lsRecursive(path: string): string[]
Lists all files recursively (full paths).
Parameters:
path- Directory path to scan
Returns: Array of all file paths (recursive)
Examples:
const allFiles = __sys__.$lsRecursive("src");
console.log(allFiles);
// [
// "/project/src/index.ts",
// "/project/src/components/Button.tsx",
// "/project/src/components/Input.tsx",
// "/project/src/utils/helpers.ts"
// ]
// Find all TypeScript files
const tsFiles = allFiles.filter((f) => f.endsWith(".ts"));
console.log(`Found ${tsFiles.length} TypeScript files`);
Use Cases:
- Finding all files in a tree
- Recursive processing
- File discovery
$emptyDir(path: string): void
Removes all contents of a directory.
Parameters:
path- Directory path to empty
Examples:
// Clear cache directory
__sys__.$emptyDir("cache");
// Clear build output
__sys__.$emptyDir("dist");
// Clear temporary files
__sys__.$emptyDir("temp");
Warning: This permanently deletes all files and subdirectories. Use with caution.
Common Patterns
Directory Tree Creation
function createProjectStructure(projectName: string): void {
const dirs = [
`${projectName}/src`,
`${projectName}/src/components`,
`${projectName}/src/utils`,
`${projectName}/tests`,
`${projectName}/docs`,
`${projectName}/public`,
];
dirs.forEach((dir) => __sys__.$mkdir(dir));
// Create initial files
__sys__.$write(`${projectName}/README.md`, `# ${projectName}`);
__sys__.$write(`${projectName}/src/index.ts`, "// Entry point");
}
createProjectStructure("my-app");
Directory Scanning
function scanDirectory(path: string): {
files: number;
dirs: number;
totalSize: number;
} {
const allFiles = __sys__.$lsRecursive(path);
const dirs = __sys__.$lsDirs(path);
const totalSize = allFiles.reduce((sum, file) => {
return sum + __sys__.$stats(file).size;
}, 0);
return {
files: allFiles.length,
dirs: dirs.length,
totalSize,
};
}
const info = scanDirectory("src");
console.log(
`Files: ${info.files}, Dirs: ${info.dirs}, Size: ${info.totalSize} bytes`
);
Organize Files by Extension
function organizeByExtension(sourceDir: string, targetDir: string): void {
const files = __sys__.$lsFiles(sourceDir);
files.forEach((file) => {
const ext = __sys__.$extname(file).slice(1) || "no-extension";
const targetFolder = __sys__.$join(targetDir, ext);
__sys__.$ensureDir(targetFolder);
const sourcePath = __sys__.$join(sourceDir, file);
const targetPath = __sys__.$join(targetFolder, file);
__sys__.$copy(sourcePath, targetPath);
});
}
organizeByExtension("downloads", "organized");
Clean Old Files
function cleanOldFiles(dir: string, maxAgeDays: number): number {
const files = __sys__.$lsRecursive(dir);
const maxAgeMs = maxAgeDays * 24 * 60 * 60 * 1000;
const now = Date.now();
let removed = 0;
files.forEach((file) => {
const stats = __sys__.$stats(file);
const age = now - stats.modified * 1000;
if (age > maxAgeMs) {
__sys__.$rm(file);
removed++;
}
});
return removed;
}
const cleaned = cleanOldFiles("logs", 30);
console.log(`Removed ${cleaned} old files`);
Directory Comparison
function compareDirectories(
dir1: string,
dir2: string
): {
onlyInDir1: string[];
onlyInDir2: string[];
common: string[];
} {
const files1 = new Set(__sys__.$ls(dir1));
const files2 = new Set(__sys__.$ls(dir2));
const onlyInDir1 = [...files1].filter((f) => !files2.has(f));
const onlyInDir2 = [...files2].filter((f) => !files1.has(f));
const common = [...files1].filter((f) => files2.has(f));
return { onlyInDir1, onlyInDir2, common };
}
const diff = compareDirectories("src", "backup/src");
console.log("Only in src:", diff.onlyInDir1);
console.log("Only in backup:", diff.onlyInDir2);
console.log("Common:", diff.common);
Mirror Directory Structure
function mirrorStructure(sourceDir: string, targetDir: string): void {
const dirs = __sys__.$lsDirs(sourceDir);
dirs.forEach((dir) => {
const sourcePath = __sys__.$join(sourceDir, dir);
const targetPath = __sys__.$join(targetDir, dir);
__sys__.$mkdir(targetPath);
// Recursively mirror subdirectories
if (__sys__.$isDir(sourcePath)) {
mirrorStructure(sourcePath, targetPath);
}
});
}
mirrorStructure("src", "backup/src");
Best Practices
1. Check Before Operations
// Good: Check if directory exists
if (__sys__.$isDir("data")) {
const files = __sys__.$ls("data");
}
// Or use ensureDir for safety
__sys__.$ensureDir("data");
const files = __sys__.$ls("data");
2. Use Full Paths for Processing
// Good: Use full paths
const files = __sys__.$lsFullPath("src");
files.forEach((file) => {
if (__sys__.$isFile(file)) {
processFile(file);
}
});
// Avoid: Reconstructing paths
const names = __sys__.$ls("src");
names.forEach((name) => {
const path = __sys__.$join("src", name); // Extra work
processFile(path);
});
3. Handle Empty Directories
function processDirectory(dir: string): void {
if (!__sys__.$isDir(dir)) {
console.error(`Not a directory: ${dir}`);
return;
}
const files = __sys__.$ls(dir);
if (files.length === 0) {
console.log(`Directory is empty: ${dir}`);
return;
}
// Process files
files.forEach((file) => {
// ...
});
}
4. Use Recursive Operations Carefully
// For large directories, consider limiting depth
function lsRecursiveWithLimit(
path: string,
maxDepth: number,
currentDepth: number = 0
): string[] {
if (currentDepth >= maxDepth) {
return [];
}
const files = __sys__.$lsFullPath(path);
let result: string[] = [];
files.forEach((file) => {
if (__sys__.$isFile(file)) {
result.push(file);
} else if (__sys__.$isDir(file)) {
result = result.concat(
lsRecursiveWithLimit(file, maxDepth, currentDepth + 1)
);
}
});
return result;
}
5. Clean Up Temporary Directories
function withTempDir<T>(callback: (tempDir: string) => T): T {
const tempDir = `temp_${Date.now()}`;
try {
__sys__.$mkdir(tempDir);
return callback(tempDir);
} finally {
if (__sys__.$exists(tempDir)) {
__sys__.$rm(tempDir);
}
}
}
const result = withTempDir((tempDir) => {
__sys__.$write(`${tempDir}/data.txt`, "temp data");
return processData(`${tempDir}/data.txt`);
});
Performance Considerations
Directory Listing Performance
- Small directories (<100 files): <5ms
- Medium directories (100-1000 files): 5-20ms
- Large directories (>1000 files): 20-100ms
- Recursive operations: Depends on tree size
Optimization Tips
// Cache directory listings
const dirCache = new Map<string, string[]>();
function cachedLs(path: string, ttl: number = 60000): string[] {
const key = path;
const cached = dirCache.get(key);
if (cached) {
return cached;
}
const files = __sys__.$ls(path);
dirCache.set(key, files);
setTimeout(() => dirCache.delete(key), ttl);
return files;
}
Error Handling
import { XyPrissError } from "xypriss";
try {
const files = __sys__.$ls("nonexistent");
} catch (error) {
if (error instanceof XyPrissError) {
console.error(`Failed to list directory: ${error.message}`);
}
}
// Safe directory listing
function safeLs(path: string): string[] {
if (!__sys__.$exists(path)) {
return [];
}
if (!__sys__.$isDir(path)) {
console.warn(`Not a directory: ${path}`);
return [];
}
return __sys__.$ls(path);
}
Platform Considerations
Unix/Linux/macOS
- Case-sensitive file names
- Hidden files start with
. - No restrictions on special characters (except
/)
Windows
- Case-insensitive file names
- Hidden files use file attributes
- Reserved names:
CON,PRN,AUX,NUL, etc.
Cross-Platform Code
// Filter hidden files (cross-platform)
function getVisibleFiles(dir: string): string[] {
const files = __sys__.$ls(dir);
return files.filter((f) => !f.startsWith("."));
}
// Handle case sensitivity
function findFileIgnoreCase(dir: string, filename: string): string | null {
const files = __sys__.$ls(dir);
const found = files.find((f) => f.toLowerCase() === filename.toLowerCase());
return found || null;
}
Related Documentation
Version: XyPriss v6.0.0+
Last Updated: 2026-01-12