// 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;
}
}
}
}