Skip to content

Commit

Permalink
Merge pull request #64 from linksplatform/FreePhoenix
Browse files Browse the repository at this point in the history
Add TemporaryFiles, TemporaryFile
  • Loading branch information
Konard authored Jul 2, 2021
2 parents 87ea911 + ec57ddb commit 5c128bd
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 9 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ jobs:
with:
submodules: true
- name: Test
run: dotnet test -c Release -f net5
run: |
dotnet build
dotnet test -c Release -f net5
- name: Generate PDF with CSharp code
if: github.event_name == 'push'
run: |
Expand Down
8 changes: 7 additions & 1 deletion Platform.IO.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ VisualStudioVersion = 16.0.29102.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Platform.IO", "csharp\Platform.IO\Platform.IO.csproj", "{E301688F-3737-4455-B5FC-A654A6A6D5A9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Platform.IO.Tests", "csharp\Platform.IO.Tests\Platform.IO.Tests.csproj", "{A3ACEE51-4281-4024-8558-24E5ED8D5E1A}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Platform.IO.Tests", "csharp\Platform.IO.Tests\Platform.IO.Tests.csproj", "{A3ACEE51-4281-4024-8558-24E5ED8D5E1A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TemporaryFileTest", "csharp\TemporaryFileTest\TemporaryFileTest.csproj", "{DCA635ED-E76E-4548-BE1F-6B87E64E5AB2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -21,6 +23,10 @@ Global
{A3ACEE51-4281-4024-8558-24E5ED8D5E1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A3ACEE51-4281-4024-8558-24E5ED8D5E1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A3ACEE51-4281-4024-8558-24E5ED8D5E1A}.Release|Any CPU.Build.0 = Release|Any CPU
{DCA635ED-E76E-4548-BE1F-6B87E64E5AB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DCA635ED-E76E-4548-BE1F-6B87E64E5AB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCA635ED-E76E-4548-BE1F-6B87E64E5AB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCA635ED-E76E-4548-BE1F-6B87E64E5AB2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
35 changes: 35 additions & 0 deletions csharp/Platform.IO.Tests/TemporaryFileTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Xunit;
using System.IO;
using System.Diagnostics;

namespace Platform.IO.Tests
{
public class TemporaryFileTests
{
[Fact]
public void TemporaryFileTest()
{
using Process process = new();
process.StartInfo.FileName = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "TemporaryFileTest", "bin", "Debug", "net5", "TemporaryFileTest"));
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
var path = process.StandardOutput.ReadLine();
Assert.True(File.Exists(path));
process.WaitForExit();
Assert.False(File.Exists(path));
}

[Fact]
public void TemporaryFileTestWithoutConsoleApp()
{
string fileName;
using (TemporaryFile tempFile = new())
{
fileName = tempFile;
Assert.True(File.Exists(fileName));
}
Assert.False(File.Exists(fileName));
}
}
}
2 changes: 0 additions & 2 deletions csharp/Platform.IO/ConsoleCancellation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using Platform.Disposables;
using Platform.Threading;

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

namespace Platform.IO
{
/// <summary>
Expand Down
53 changes: 53 additions & 0 deletions csharp/Platform.IO/FileHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -290,5 +290,58 @@ public static void DeleteAll(string directory, string searchPattern, SearchOptio
File.Delete(file);
}
}

/// <summary>
/// <para>Trincates the file at the <paramref name="path"/>.</para>
/// <para>Очищает содержимое файла по пути <paramref name="path"/>.</para>
/// </summary>
/// <param name="path">
/// <para>A path to a file to be truncated.</para>
/// <para>Путь к файлу для очистки содержимого.</para>
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Truncate(string path) => File.Open(path, FileMode.Truncate).Dispose();

/// <summary>
/// <para>Appends the <paramref name="content"/> to a file at the <paramref name="path"/>.</para>
/// <para>Добавляет <paramref name="content"/> в конец файла по пути <paramref name="path"/>.</para>
/// </summary>
/// <param name="path">
/// <para>The path to a file to be appended by the <paramref name="content"/>.</para>
/// <para>Путь к файлу для добавления <paramref name="content"/> в конец файла.</para>
/// </param>
/// <param name="content">
/// <para>A content to be appended to a file at the file at the <paramref name="path"/>.</para>
/// <para>Содержимое для добавления в конец файла по пути <paramref name="path"/>.</para>
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void AppendLine(string path, string content)
{
using var writer = File.AppendText(path);
writer.WriteLine(content);
}

/// <summary>
/// <para>Performs the <paramref name="action"/> for each line of a file at the <paramref name="path"/>.</para>
/// <para>Выполняет <paramref name="action"/> для каждой строчки файла по пути <paramref name="path"/>.</para>
/// </summary>
/// <param name="path">
/// <para>A path to a file to perform the <paramref name="action"/> for each line of the file.</para>
/// <para>Путь к файлу для выполнения <paramref name="action"/> для каждой строки файла.</para>
/// </param>
/// <param name="action">
/// <para>An action to be performed for each line of a file at the <paramref name="path"/>.</para>
/// <para>Действие выполняемое для каждой строчки файла по пути <paramref name="path"/>.</para>
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void EachLine(string path, Action<string> action)
{
using var reader = new StreamReader(path);
string line;
while ((line = reader.ReadLine()) != null)
{
action(line);
}
}
}
}
8 changes: 3 additions & 5 deletions csharp/Platform.IO/Platform.IO.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Description>LinksPlatform's Platform.IO Class Library</Description>
<Copyright>Konstantin Diachenko</Copyright>
<AssemblyTitle>Platform.IO</AssemblyTitle>
<VersionPrefix>0.2.1</VersionPrefix>
<VersionPrefix>0.2.2</VersionPrefix>
<Authors>Konstantin Diachenko</Authors>
<TargetFrameworks>net472;netstandard2.0;netstandard2.1;net5</TargetFrameworks>
<AssemblyName>Platform.IO</AssemblyName>
Expand All @@ -24,10 +24,8 @@
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<LangVersion>latest</LangVersion>
<PackageReleaseNotes>Platform.Threading dependency updated from 0.2.0 to 0.2.1.
Platform.Unsafe dependency updated from 0.4.0 to 0.4.1.
ConsoleHelpers.Debug method with single string argument added.
Refactoring, issues fix.</PackageReleaseNotes>
<PackageReleaseNotes>TemporaryFiles, TemporaryFile classes are added.
Truncate, AppendLine, EachLine methods are added to the FileHelpers class.</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('net4')) AND '$(MSBuildRuntimeType)' == 'Core' AND '$(OS)' != 'Windows_NT'">
Expand Down
62 changes: 62 additions & 0 deletions csharp/Platform.IO/TemporaryFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Platform.Disposables;
using System;
using System.IO;
using System.Runtime.CompilerServices;

namespace Platform.IO
{
/// <summary>
/// <para>Represents a self-deleting temporary file.</para>
/// <para>Представляет самоудаляющийся временный файл.</para>
/// </summary>
public class TemporaryFile : DisposableBase
{
/// <summary>
/// <para>Gets a temporary file path.</para>
/// <para>Возвращает путь к временному файлу.</para>
/// </summary>
public readonly string Filename;

/// <summary>
/// <para>Converts the <see cref="TemporaryFile"/> instance to <see cref="string"/> using the <see cref="Filename"/> field value.</para>
/// <para>Преобразует экземпляр <see cref="TemporaryFile"/> в <see cref="string"/> используя поле <see cref="Filename"/>.</para>
/// </summary>
/// <param name="file">
/// <para>A <see cref="TemporaryFile"/> instance.</para>
/// <para>Экземпляр <see cref="TemporaryFile"/>.</para>
/// </param>
/// <returns>
/// <para>Path to the temporary file.</para>
/// <para>Путь к временному файлу.</para>
/// </returns>
public static implicit operator string(TemporaryFile file) => file.Filename;

/// <summary>
/// <para>Initializes a <see cref="TemporaryFile"/> instance.</para>
/// <para>Инициализирует экземпляр класса <see cref="TemporaryFile"/>.</para>
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TemporaryFile() => Filename = TemporaryFiles.UseNew();

/// <summary>
/// <para>Deletes the temporary file.</para>
/// <para>Удаляет временный файл.</para>
/// </summary>
/// <param name="manual">
/// <para>A <see cref="Boolean"/> value that determines whether the disposal was triggered manually (by the developer's code) or was executed automatically without an explicit indication from a developer.</para>
/// <para>Значение типа <see cref="Boolean"/>, определяющие было ли высвобождение вызвано вручную (кодом разработчика) или же выполнилось автоматически без явного указания со стороны разработчика.</para>
/// </param>
/// <param name="wasDisposed">
/// <para>A <see cref="Boolean"/> value that determines whether the <see cref="TemporaryFile"/> was released before a call to this method.</para>
/// <para>Значение типа <see cref="Boolean"/>, определяющие были ли освобождены ресурсы, используемые <see cref="TemporaryFile"/> до вызова данного метода.</para>
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override void Dispose(bool manual, bool wasDisposed)
{
if (!wasDisposed)
{
File.Delete(Filename);
}
}
}
}
60 changes: 60 additions & 0 deletions csharp/Platform.IO/TemporaryFiles.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace Platform.IO
{
/// <summary>
/// <para>Represents the set of helper methods to work with temporary files.</para>
/// <para>Представляет набор вспомогательных методов для работы с временными файлами.</para>
/// </summary>
public class TemporaryFiles
{
private const string UserFilesListFileNamePrefix = ".used-temporary-files.txt";
private static readonly object UsedFilesListLock = new();
private static readonly string UsedFilesListFilename = Assembly.GetExecutingAssembly().Location + UserFilesListFileNamePrefix;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AddToUsedFilesList(string filename)
{
lock (UsedFilesListLock)
{
FileHelpers.AppendLine(UsedFilesListFilename, filename);
}
}

/// <summary>
/// <para>Gets a temporary file and adds it to the used files list.</para>
/// <para>Получает временный файл и добавляет его в список использованных файлов.</para>
/// </summary>
/// <returns>
/// <para>The temporary file path.</para>
/// <para>Путь временного файла.</para>
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string UseNew()
{
var filename = Path.GetTempFileName();
AddToUsedFilesList(filename);
return filename;
}

/// <summary>
/// <para>Deletes all previously used temporary files and clears the files list.</para>
/// <para>Удаляет все ранее использованные временные файлы и очищает список файлов.</para>
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void DeleteAllPreviouslyUsed()
{
lock (UsedFilesListLock)
{
var listFilename = UsedFilesListFilename;
if (File.Exists(listFilename))
{
FileHelpers.EachLine(listFilename, File.Delete);
FileHelpers.Truncate(listFilename);
}
}
}
}
}
16 changes: 16 additions & 0 deletions csharp/TemporaryFileTest/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using Platform.IO;
using System.IO;
using System.Reflection;

namespace TemporaryFileTest
{
class Program
{
static void Main()
{
using TemporaryFile tempFile = new();
Console.WriteLine(tempFile);
}
}
}
12 changes: 12 additions & 0 deletions csharp/TemporaryFileTest/TemporaryFileTest.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Platform.IO\Platform.IO.csproj" />
</ItemGroup>

</Project>

0 comments on commit 5c128bd

Please sign in to comment.