// MIT License - Copyright (c) 2025 wallstop // Full license text: https://github.com/wallstop/unity-helpers/blob/main/LICENSE namespace WallstopStudios.UnityHelpers.Core.Helper { using System; using System.IO; using System.Threading; using System.Threading.Tasks; using UnityEngine; /// /// Lightweight file I/O helpers with safe default behaviors. /// /// /// Focuses on project asset file management. Methods are safe to call in editor and player. /// public static class FileHelper { /// /// Creates a file at the specified path if it does not exist, optionally writing initial contents. /// /// Absolute or relative file path. /// Optional initial contents (defaults to empty). /// True if the file was created; false if it already existed or creation failed. public static bool InitializePath(string path, byte[] contents = null) { if (File.Exists(path)) { return false; } string directory = Path.GetDirectoryName(path); if (!string.IsNullOrWhiteSpace(directory)) { Directory.CreateDirectory(directory); } try { using FileStream fileStream = new( path, FileMode.CreateNew, FileAccess.Write, FileShare.None ); contents ??= Array.Empty(); fileStream.Write(contents, 0, contents.Length); return true; } catch (IOException e) { Debug.LogError($"File {path} already exists, not creating.\n{e}"); return false; } } /// /// Asynchronously copies a file to a new path using a buffered stream. /// /// Source file path. /// Destination file path (overwrites). /// Buffer size in bytes (default 81920). /// Optional cancellation token. /// True on success; false if the copy fails or is cancelled. public static async ValueTask CopyFileAsync( string sourcePath, string destinationPath, int bufferSize = 81920, CancellationToken cancellationToken = default ) { try { await using FileStream sourceStream = new( sourcePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync: true ); await using FileStream destinationStream = new( destinationPath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize, useAsync: true ); await sourceStream.CopyToAsync(destinationStream, bufferSize, cancellationToken); return true; } catch { return false; } } } }