using System; using System.IO; using System.Text; namespace TweetLib.Core.Utils { public static class FileUtils { public static void CreateDirectoryForFile(string file) { string? dir = Path.GetDirectoryName(file); if (dir == null) { throw new ArgumentException("Invalid file path: " + file); } else if (dir.Length > 0) { Directory.CreateDirectory(dir); } } public static bool CheckFolderWritePermission(string path) { string testFile = Path.Combine(path, ".test"); try { Directory.CreateDirectory(path); using (File.Create(testFile)) {} File.Delete(testFile); return true; } catch { return false; } } public static bool FileExistsAndNotEmpty(string path) { try { return new FileInfo(path).Length > 0; } catch { return false; } } public static string? ReadFileOrNull(string path) { try { return File.ReadAllText(path, Encoding.UTF8); } catch (Exception e) { App.ErrorHandler.Log("Error reading file: " + path); App.ErrorHandler.Log(e.ToString()); return null; } } public static string ResolveRelativePathSafely(string rootFolder, string relativePath) { string fullPath = Path.Combine(rootFolder, relativePath); try { string folderPathName = new DirectoryInfo(rootFolder).FullName; DirectoryInfo currentInfo = new DirectoryInfo(fullPath); // initially points to the file, which is convenient for the Attributes check below DirectoryInfo? parentInfo = currentInfo.Parent; while (parentInfo != null) { if (currentInfo.Exists && currentInfo.Attributes.HasFlag(FileAttributes.ReparsePoint)) { return string.Empty; // no reason why there should be any files/folders with symlinks, junctions, or any other crap } if (parentInfo.FullName == folderPathName) { return fullPath; } currentInfo = parentInfo; parentInfo = currentInfo.Parent; } } catch { // ignore } return string.Empty; } } }