├── .gitattributes ├── .gitignore ├── AsyncIO.Tests ├── AsyncIO.Tests.xproj ├── IntegrationTests │ └── FileSystem │ │ └── FileTests.cs ├── Properties │ └── AssemblyInfo.cs └── project.json ├── AsyncIO.sln ├── AsyncIO.sln.DotSettings ├── AsyncIO ├── AsyncIO.xproj ├── FileSystem │ ├── AsyncFile.cs │ ├── Extensions │ │ └── FileInfoExtensions.cs │ └── PathValidator.cs ├── Properties │ └── AssemblyInfo.cs └── project.json ├── LICENSE ├── README.md └── global.json /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | build/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | 28 | # MSTest test Results 29 | [Tt]est[Rr]esult*/ 30 | [Bb]uild[Ll]og.* 31 | 32 | # NUNIT 33 | *.VisualState.xml 34 | TestResult.xml 35 | 36 | # Build Results of an ATL Project 37 | [Dd]ebugPS/ 38 | [Rr]eleasePS/ 39 | dlldata.c 40 | 41 | # DNX 42 | project.lock.json 43 | artifacts/ 44 | 45 | *_i.c 46 | *_p.c 47 | *_i.h 48 | *.ilk 49 | *.meta 50 | *.obj 51 | *.pch 52 | *.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.tmp 61 | *.tmp_proj 62 | *.log 63 | *.vspscc 64 | *.vssscc 65 | .builds 66 | *.pidb 67 | *.svclog 68 | *.scc 69 | 70 | # Chutzpah Test files 71 | _Chutzpah* 72 | 73 | # Visual C++ cache files 74 | ipch/ 75 | *.aps 76 | *.ncb 77 | *.opensdf 78 | *.sdf 79 | *.cachefile 80 | 81 | # Visual Studio profiler 82 | *.psess 83 | *.vsp 84 | *.vspx 85 | 86 | # TFS 2012 Local Workspace 87 | $tf/ 88 | 89 | # Guidance Automation Toolkit 90 | *.gpState 91 | 92 | # ReSharper is a .NET coding add-in 93 | _ReSharper*/ 94 | *.[Rr]e[Ss]harper 95 | *.DotSettings.user 96 | 97 | # JustCode is a .NET coding add-in 98 | .JustCode 99 | 100 | # TeamCity is a build add-in 101 | _TeamCity* 102 | 103 | # DotCover is a Code Coverage Tool 104 | *.dotCover 105 | 106 | # NCrunch 107 | _NCrunch_* 108 | .*crunch*.local.xml 109 | 110 | # MightyMoose 111 | *.mm.* 112 | AutoTest.Net/ 113 | 114 | # Web workbench (sass) 115 | .sass-cache/ 116 | 117 | # Installshield output folder 118 | [Ee]xpress/ 119 | 120 | # DocProject is a documentation generator add-in 121 | DocProject/buildhelp/ 122 | DocProject/Help/*.HxT 123 | DocProject/Help/*.HxC 124 | DocProject/Help/*.hhc 125 | DocProject/Help/*.hhk 126 | DocProject/Help/*.hhp 127 | DocProject/Help/Html2 128 | DocProject/Help/html 129 | 130 | # Click-Once directory 131 | publish/ 132 | 133 | # Publish Web Output 134 | *.[Pp]ublish.xml 135 | *.azurePubxml 136 | ## TODO: Comment the next line if you want to checkin your 137 | ## web deploy settings but do note that will include unencrypted 138 | ## passwords 139 | #*.pubxml 140 | 141 | *.publishproj 142 | 143 | # NuGet Packages 144 | *.nupkg 145 | # The packages folder can be ignored because of Package Restore 146 | **/packages/* 147 | # except build/, which is used as an MSBuild target. 148 | !**/packages/build/ 149 | # Uncomment if necessary however generally it will be regenerated when needed 150 | #!**/packages/repositories.config 151 | 152 | # Windows Azure Build Output 153 | csx/ 154 | *.build.csdef 155 | 156 | # Windows Store app package directory 157 | AppPackages/ 158 | 159 | # Visual Studio cache files 160 | # files ending in .cache can be ignored 161 | *.[Cc]ache 162 | # but keep track of directories ending in .cache 163 | !*.[Cc]ache/ 164 | 165 | # Others 166 | ClientBin/ 167 | [Ss]tyle[Cc]op.* 168 | ~$* 169 | *~ 170 | *.dbmdl 171 | *.dbproj.schemaview 172 | *.pfx 173 | *.publishsettings 174 | node_modules/ 175 | orleans.codegen.cs 176 | 177 | # RIA/Silverlight projects 178 | Generated_Code/ 179 | 180 | # Backup & report files from converting an old project file 181 | # to a newer Visual Studio version. Backup files are not needed, 182 | # because we have git ;-) 183 | _UpgradeReport_Files/ 184 | Backup*/ 185 | UpgradeLog*.XML 186 | UpgradeLog*.htm 187 | 188 | # SQL Server files 189 | *.mdf 190 | *.ldf 191 | 192 | # Business Intelligence projects 193 | *.rdl.data 194 | *.bim.layout 195 | *.bim_*.settings 196 | 197 | # Microsoft Fakes 198 | FakesAssemblies/ 199 | 200 | # Node.js Tools for Visual Studio 201 | .ntvs_analysis.dat 202 | 203 | # Visual Studio 6 build log 204 | *.plg 205 | 206 | # Visual Studio 6 workspace options file 207 | *.opt 208 | 209 | # LightSwitch generated files 210 | GeneratedArtifacts/ 211 | _Pvt_Extensions/ 212 | ModelManifest.xml 213 | -------------------------------------------------------------------------------- /AsyncIO.Tests/AsyncIO.Tests.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | 2a6b24e4-96d0-408f-9508-d7918a41ea45 11 | AsyncIO.Tests 12 | .\obj 13 | .\bin\ 14 | v4.5 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /AsyncIO.Tests/IntegrationTests/FileSystem/FileTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using AsyncIO.FileSystem; 8 | using NUnit.Framework; 9 | 10 | namespace AsyncIO.Tests.IntegrationTests.FileSystem 11 | { 12 | public class FileTests 13 | { 14 | private const string FileTestFolder = "FileTests"; 15 | 16 | private static Encoding[] encodings = 17 | { 18 | Encoding.ASCII, Encoding.BigEndianUnicode, Encoding.UTF32, Encoding.UTF7, Encoding.UTF8, Encoding.Unicode 19 | }; 20 | 21 | [TestFixture] 22 | public class AppendAllLinesAsyncMethod 23 | { 24 | private readonly string appendAllLinesTestFolder = Path.Combine(FileTestFolder, nameof(AppendAllLinesAsyncMethod)); 25 | 26 | [Test] 27 | public async Task Default_LinesAppended() 28 | { 29 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 30 | var path = Path.Combine(appendAllLinesTestFolder, nameof(Default_LinesAppended)); 31 | 32 | Directory.CreateDirectory(appendAllLinesTestFolder); 33 | File.WriteAllLines(path, contents); 34 | 35 | await AsyncFile.AppendAllLinesAsync(path, contents); 36 | 37 | contents.AddRange(Enumerable.Repeat("This is a test line.", 150)); 38 | 39 | var result = File.ReadAllLines(path); 40 | 41 | CollectionAssert.AreEqual(contents, result); 42 | } 43 | 44 | [TestCaseSource(typeof(FileTests), nameof(encodings))] 45 | public async Task LinesAppendedWithEncoding(Encoding encoding) 46 | { 47 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 48 | var path = Path.Combine(appendAllLinesTestFolder, nameof(LinesAppendedWithEncoding)); 49 | Directory.CreateDirectory(appendAllLinesTestFolder); 50 | File.WriteAllLines(path, contents, encoding); 51 | 52 | await AsyncFile.AppendAllLinesAsync(path, contents, encoding); 53 | 54 | contents.AddRange(Enumerable.Repeat("This is a test line.", 150)); 55 | 56 | var result = File.ReadAllLines(path, encoding); 57 | 58 | CollectionAssert.AreEqual(contents, result); 59 | } 60 | 61 | [Test] 62 | public void CancellationToken_LinesAppended() 63 | { 64 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 65 | var path = Path.Combine(appendAllLinesTestFolder, nameof(CancellationToken_LinesAppended)); 66 | Directory.CreateDirectory(appendAllLinesTestFolder); 67 | File.WriteAllLines(path, contents); 68 | 69 | contents.AddRange(Enumerable.Repeat("This is a test line.", 150000)); 70 | 71 | var cancellationTokenSource = new CancellationTokenSource(); 72 | 73 | Assert.ThrowsAsync( 74 | async () => 75 | { 76 | var task = AsyncFile.AppendAllLinesAsync(path, contents, cancellationTokenSource.Token); 77 | cancellationTokenSource.Cancel(); 78 | await task; 79 | }); 80 | 81 | var result = File.ReadAllLines(path); 82 | 83 | Assert.IsTrue(contents.Count > result.Length); 84 | } 85 | 86 | [Test] 87 | public void NullContent_ExceptionThrown() 88 | { 89 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 90 | var path = Path.Combine(appendAllLinesTestFolder, nameof(NullEncoding_ExceptionThrown)); 91 | 92 | Directory.CreateDirectory(appendAllLinesTestFolder); 93 | 94 | Assert.ThrowsAsync(async () => await AsyncFile.AppendAllLinesAsync(path, null)); 95 | } 96 | 97 | [Test] 98 | public void NullEncoding_ExceptionThrown() 99 | { 100 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 101 | var path = Path.Combine(appendAllLinesTestFolder, nameof(NullEncoding_ExceptionThrown)); 102 | 103 | Directory.CreateDirectory(appendAllLinesTestFolder); 104 | 105 | Assert.ThrowsAsync(async () => await AsyncFile.AppendAllLinesAsync(path, contents, null)); 106 | } 107 | 108 | } 109 | 110 | [TestFixture] 111 | public class AppendAllTextAsyncMethod 112 | { 113 | private readonly string appendAllTextTestFolder = Path.Combine(FileTestFolder, nameof(AppendAllTextAsyncMethod)); 114 | 115 | [Test] 116 | public async Task Default_TextAppended() 117 | { 118 | var contents = string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 119 | var path = Path.Combine(appendAllTextTestFolder, nameof(Default_TextAppended)); 120 | 121 | Directory.CreateDirectory(appendAllTextTestFolder); 122 | File.WriteAllText(path, contents); 123 | 124 | await AsyncFile.AppendAllTextAsync(path, contents); 125 | 126 | contents += string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 127 | 128 | var result = File.ReadAllText(path); 129 | 130 | Assert.AreEqual(contents, result); 131 | } 132 | 133 | [TestCaseSource(typeof(FileTests), nameof(encodings))] 134 | public async Task TextAppendedWithEncoding(Encoding encoding) 135 | { 136 | var contents = string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 137 | var path = Path.Combine(appendAllTextTestFolder, nameof(TextAppendedWithEncoding)); 138 | 139 | Directory.CreateDirectory(appendAllTextTestFolder); 140 | File.WriteAllText(path, contents, encoding); 141 | 142 | await AsyncFile.AppendAllTextAsync(path, contents, encoding); 143 | 144 | contents += string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 145 | 146 | var result = File.ReadAllText(path, encoding); 147 | 148 | Assert.AreEqual(contents, result); 149 | } 150 | 151 | [Test] 152 | public void NullContent_ExceptionThrown() 153 | { 154 | var path = Path.Combine(appendAllTextTestFolder, nameof(NullContent_ExceptionThrown)); 155 | 156 | Directory.CreateDirectory(appendAllTextTestFolder); 157 | 158 | Assert.ThrowsAsync(async () => await AsyncFile.AppendAllTextAsync(path, null)); 159 | } 160 | 161 | [Test] 162 | public void AppendAllTextAsync_NullEncoding_ExceptionThrown() 163 | { 164 | var contents = "This is a test line."; 165 | var path = Path.Combine(appendAllTextTestFolder, "AppendAllLinesAsync_Default_LinesAppended"); 166 | 167 | Directory.CreateDirectory(appendAllTextTestFolder); 168 | 169 | Assert.ThrowsAsync(async () => await AsyncFile.AppendAllTextAsync(path, contents, null)); 170 | } 171 | } 172 | 173 | [TestFixture] 174 | public class CopyAsyncMethod 175 | { 176 | private readonly string copyTestFolder = Path.Combine(FileTestFolder, nameof(CopyAsyncMethod)); 177 | 178 | [Test] 179 | public async Task Default_FileCopied() 180 | { 181 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 182 | var path = Path.Combine(copyTestFolder, nameof(Default_FileCopied)); 183 | 184 | 185 | Directory.CreateDirectory(copyTestFolder); 186 | File.WriteAllLines(path, contents); 187 | 188 | var copyPath = Path.Combine(copyTestFolder, $"{nameof(Default_FileCopied)}_Copy"); 189 | File.Delete(copyPath); 190 | 191 | await AsyncFile.CopyAsync(path, copyPath); 192 | 193 | var result = File.ReadAllLines(copyPath); 194 | CollectionAssert.AreEqual(contents, result); 195 | } 196 | 197 | [Test] 198 | public async Task Overwrite_FileCopied() 199 | { 200 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 201 | var path = Path.Combine(copyTestFolder, nameof(Overwrite_FileCopied)); 202 | 203 | Directory.CreateDirectory(copyTestFolder); 204 | File.WriteAllLines(path, contents); 205 | 206 | var copyPath = Path.Combine(copyTestFolder, $"{nameof(Overwrite_FileCopied)}_Copy"); 207 | if (!File.Exists(copyPath)) 208 | File.Create(copyPath).Dispose(); 209 | 210 | await AsyncFile.CopyAsync(path, copyPath, true); 211 | 212 | var result = File.ReadAllLines(copyPath); 213 | CollectionAssert.AreEqual(contents, result); 214 | } 215 | 216 | [Test] 217 | public void CancellationToken_ExceptionThrown() 218 | { 219 | var contents = Enumerable.Repeat("This is a test line.", 150000).ToList(); 220 | var path = Path.Combine(copyTestFolder, nameof(CancellationToken_ExceptionThrown)); 221 | 222 | Directory.CreateDirectory(copyTestFolder); 223 | File.WriteAllLines(path, contents); 224 | 225 | var copyPath = Path.Combine(copyTestFolder, $"{nameof(CancellationToken_ExceptionThrown)}_Copy"); 226 | File.Delete(copyPath); 227 | 228 | var tokenSource = new CancellationTokenSource(); 229 | Assert.ThrowsAsync(async () => 230 | { 231 | var task = AsyncFile.CopyAsync(path, copyPath, tokenSource.Token); 232 | tokenSource.Cancel(); 233 | await task; 234 | }); 235 | 236 | var result = File.ReadAllLines(copyPath); 237 | Assert.IsTrue(contents.Count > result.Length); 238 | } 239 | 240 | [Test] 241 | public void CancellationTokenOverwrite_ExceptionThrown() 242 | { 243 | var contents = Enumerable.Repeat("This is a test line.", 300000).ToList(); 244 | var path = Path.Combine(copyTestFolder, nameof(CancellationTokenOverwrite_ExceptionThrown)); 245 | 246 | Directory.CreateDirectory(copyTestFolder); 247 | File.WriteAllLines(path, contents); 248 | 249 | var copyPath = Path.Combine(copyTestFolder, $"{nameof(CancellationTokenOverwrite_ExceptionThrown)}_Copy"); 250 | if (!File.Exists(copyPath)) 251 | File.Create(copyPath).Dispose(); 252 | 253 | var tokenSource = new CancellationTokenSource(); 254 | Assert.ThrowsAsync(async () => 255 | { 256 | var task = AsyncFile.CopyAsync(path, copyPath, true, tokenSource.Token); 257 | tokenSource.Cancel(); 258 | await task; 259 | }); 260 | 261 | var result = File.ReadAllLines(copyPath); 262 | Assert.IsTrue(contents.Count > result.Length); 263 | } 264 | } 265 | 266 | public class DeleteAsyncMethod 267 | { 268 | private readonly string deleteTestFolder = Path.Combine(FileTestFolder, nameof(DeleteAsyncMethod)); 269 | 270 | [Test] 271 | public async Task Default_FileDeleted() 272 | { 273 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 274 | var path = Path.Combine(deleteTestFolder, nameof(Default_FileDeleted)); 275 | 276 | 277 | Directory.CreateDirectory(deleteTestFolder); 278 | File.WriteAllLines(path, contents); 279 | 280 | await AsyncFile.DeleteAsync(path); 281 | 282 | Assert.IsFalse(File.Exists(path)); 283 | } 284 | 285 | [Test] 286 | public async Task NotExists_FileDeleted() 287 | { 288 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 289 | var path = Path.Combine(deleteTestFolder, nameof(NotExists_FileDeleted)); 290 | 291 | 292 | Directory.CreateDirectory(deleteTestFolder); 293 | File.WriteAllLines(path, contents); 294 | if (File.Exists(path)) 295 | { 296 | File.Delete(path); 297 | } 298 | 299 | await AsyncFile.DeleteAsync(path); 300 | 301 | Assert.IsFalse(File.Exists(path)); 302 | } 303 | } 304 | 305 | [TestFixture] 306 | public class MoveAsyncMethod 307 | { 308 | 309 | private readonly string moveTestFolder = Path.Combine(FileTestFolder, nameof(MoveAsyncMethod)); 310 | 311 | [Test] 312 | public async Task Default_FileMoved() 313 | { 314 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 315 | var path = Path.Combine(moveTestFolder, nameof(Default_FileMoved)); 316 | 317 | Directory.CreateDirectory(moveTestFolder); 318 | File.WriteAllLines(path, contents); 319 | 320 | var movePath = Path.Combine(moveTestFolder, $"{nameof(Default_FileMoved)}_Moved"); 321 | File.Delete(movePath); 322 | 323 | await AsyncFile.MoveAsync(path, movePath); 324 | 325 | var result = File.ReadAllLines(movePath); 326 | CollectionAssert.AreEqual(contents, result); 327 | Assert.IsFalse(File.Exists(path)); 328 | } 329 | 330 | [Test] 331 | public void Overwrite_ExceptionThrown() 332 | { 333 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 334 | var path = Path.Combine(moveTestFolder, nameof(Overwrite_ExceptionThrown)); 335 | 336 | Directory.CreateDirectory(moveTestFolder); 337 | File.WriteAllLines(path, contents); 338 | 339 | var movePath = Path.Combine(moveTestFolder, $"{nameof(Overwrite_ExceptionThrown)}_Moved"); 340 | if (!File.Exists(movePath)) 341 | File.Create(movePath).Dispose(); 342 | 343 | Assert.ThrowsAsync(async () => await AsyncFile.MoveAsync(path, movePath)); 344 | } 345 | 346 | [Test] 347 | public async Task CancellationToken_ExceptionThrown() 348 | { 349 | var contents = Enumerable.Repeat("This is a test line.", 300000).ToList(); 350 | var path = Path.Combine(moveTestFolder, nameof(CancellationToken_ExceptionThrown)); 351 | 352 | Directory.CreateDirectory(moveTestFolder); 353 | File.WriteAllLines(path, contents); 354 | 355 | var movePath = Path.Combine(moveTestFolder, $"{nameof(CancellationToken_ExceptionThrown)}_Moved"); 356 | File.Delete(movePath); 357 | 358 | var tokenSource = new CancellationTokenSource(); 359 | Assert.ThrowsAsync(async () => 360 | { 361 | var task = AsyncFile.MoveAsync(path, movePath, tokenSource.Token); 362 | tokenSource.Cancel(); 363 | await task; 364 | }); 365 | 366 | var result = File.ReadAllLines(movePath); 367 | Assert.IsTrue(contents.Count > result.Length); 368 | Assert.IsTrue(File.Exists(path)); 369 | } 370 | 371 | [Test] 372 | public async Task SamePath_FileMoved() 373 | { 374 | var contents = Enumerable.Repeat("This is a test line.", 150000).ToList(); 375 | var path = Path.Combine(moveTestFolder, nameof(SamePath_FileMoved)); 376 | 377 | Directory.CreateDirectory(moveTestFolder); 378 | File.WriteAllLines(path, contents); 379 | 380 | var movePath = path; 381 | 382 | await AsyncFile.MoveAsync(path, movePath); 383 | 384 | var result = File.ReadAllLines(movePath); 385 | CollectionAssert.AreEqual(contents, result); 386 | Assert.IsTrue(File.Exists(path)); 387 | } 388 | } 389 | 390 | [TestFixture] 391 | public class ReadAllBytesAsyncMethod 392 | { 393 | private readonly string readAllBytesTestFolder = Path.Combine(FileTestFolder, nameof(ReadAllBytesAsyncMethod)); 394 | 395 | [Test] 396 | public async Task Default_BytesRead() 397 | { 398 | var bytes = new byte[10000]; 399 | var random = new Random(); 400 | random.NextBytes(bytes); 401 | 402 | var path = Path.Combine(readAllBytesTestFolder, nameof(Default_BytesRead)); 403 | Directory.CreateDirectory(readAllBytesTestFolder); 404 | 405 | File.WriteAllBytes(path, bytes); 406 | 407 | var result = await AsyncFile.ReadAllBytesAsync(path).ConfigureAwait(false); 408 | 409 | CollectionAssert.AreEqual(bytes, result); 410 | } 411 | 412 | [Test] 413 | public void CancellationToken_BytesRead() 414 | { 415 | var bytes = new byte[100000]; 416 | var random = new Random(); 417 | random.NextBytes(bytes); 418 | 419 | var path = Path.Combine(readAllBytesTestFolder, nameof(CancellationToken_BytesRead)); 420 | Directory.CreateDirectory(readAllBytesTestFolder); 421 | 422 | File.WriteAllBytes(path, bytes); 423 | 424 | var tokenSource = new CancellationTokenSource(); 425 | Assert.ThrowsAsync(async () => 426 | { 427 | tokenSource.Cancel(); 428 | var task = AsyncFile.ReadAllBytesAsync(path, tokenSource.Token); 429 | await task; 430 | }); 431 | 432 | } 433 | } 434 | 435 | [TestFixture] 436 | public class ReadAllLinesAsyncMethod 437 | { 438 | private readonly string readAllLinesTestFolder = Path.Combine(FileTestFolder, nameof(ReadAllLinesAsyncMethod)); 439 | 440 | [Test] 441 | public async Task Default_LinesReaded() 442 | { 443 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 444 | var path = Path.Combine(readAllLinesTestFolder, nameof(Default_LinesReaded)); 445 | 446 | 447 | Directory.CreateDirectory(readAllLinesTestFolder); 448 | File.WriteAllLines(path, contents); 449 | 450 | var result = await AsyncFile.ReadAllLinesAsync(path).ConfigureAwait(false); 451 | 452 | CollectionAssert.AreEqual(contents, result); 453 | } 454 | 455 | [TestCaseSource(typeof(FileTests), nameof(encodings))] 456 | public async Task ReadAllLinesWithEncoding(Encoding encoding) 457 | { 458 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 459 | var path = Path.Combine(readAllLinesTestFolder, nameof(ReadAllLinesWithEncoding)); 460 | 461 | Directory.CreateDirectory(readAllLinesTestFolder); 462 | File.WriteAllLines(path, contents, encoding); 463 | 464 | var result = await AsyncFile.ReadAllLinesAsync(path, encoding).ConfigureAwait(false); 465 | 466 | CollectionAssert.AreEqual(contents, result); 467 | } 468 | 469 | [Test] 470 | public void CancellationToken_ExceptionThrown() 471 | { 472 | var contents = Enumerable.Repeat("This is a test line.", 30000).ToList(); 473 | var path = Path.Combine(readAllLinesTestFolder, nameof(CancellationToken_ExceptionThrown)); 474 | 475 | Directory.CreateDirectory(readAllLinesTestFolder); 476 | File.WriteAllLines(path, contents); 477 | 478 | var tokenSource = new CancellationTokenSource(); 479 | Assert.ThrowsAsync(async () => 480 | { 481 | tokenSource.Cancel(); 482 | await AsyncFile.ReadAllLinesAsync(path, tokenSource.Token).ConfigureAwait(false); 483 | }); 484 | } 485 | 486 | [Test] 487 | public void NullEncoding_ExceptionThrown() 488 | { 489 | var contents = Enumerable.Repeat("This is a test line.", 30000).ToList(); 490 | var path = Path.Combine(readAllLinesTestFolder, nameof(NullEncoding_ExceptionThrown)); 491 | 492 | Directory.CreateDirectory(FileTestFolder); 493 | File.WriteAllLines(path, contents); 494 | 495 | Assert.ThrowsAsync(async () => await AsyncFile.ReadAllLinesAsync(path, null).ConfigureAwait(false)); 496 | } 497 | } 498 | 499 | [TestFixture] 500 | public class ReadAllTextAsyncMethod 501 | { 502 | private readonly string readAllTextTestFolder = Path.Combine(FileTestFolder, nameof(ReadAllTextAsyncMethod)); 503 | 504 | [Test] 505 | public async Task Default_LinesReaded() 506 | { 507 | var contents = string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 508 | var path = Path.Combine(readAllTextTestFolder, nameof(Default_LinesReaded)); 509 | 510 | Directory.CreateDirectory(readAllTextTestFolder); 511 | File.WriteAllText(path, contents); 512 | 513 | var result = await AsyncFile.ReadAllTextAsync(path).ConfigureAwait(false); 514 | 515 | Assert.AreEqual(contents, result); 516 | } 517 | 518 | [TestCaseSource(typeof(FileTests), nameof(encodings))] 519 | public async Task ReadAllTextWithEncoding(Encoding encoding) 520 | { 521 | var contents = string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 522 | var path = Path.Combine(readAllTextTestFolder, nameof(ReadAllTextWithEncoding)); 523 | 524 | Directory.CreateDirectory(readAllTextTestFolder); 525 | File.WriteAllText(path, contents, encoding); 526 | 527 | var result = await AsyncFile.ReadAllTextAsync(path, encoding).ConfigureAwait(false); 528 | 529 | Assert.AreEqual(contents, result); 530 | } 531 | 532 | 533 | 534 | [Test] 535 | public void NullEncoding_ExceptionThrown() 536 | { 537 | var contents = string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 538 | var path = Path.Combine(readAllTextTestFolder, nameof(NullEncoding_ExceptionThrown)); 539 | 540 | Directory.CreateDirectory(readAllTextTestFolder); 541 | File.WriteAllText(path, contents); 542 | 543 | Assert.ThrowsAsync(async () => await AsyncFile.ReadAllTextAsync(path, null).ConfigureAwait(false)); 544 | } 545 | } 546 | 547 | [TestFixture] 548 | public class WriteAllBytesAsyncMethod 549 | { 550 | private readonly string writeAllBytesTestFolder = Path.Combine(FileTestFolder, nameof(WriteAllBytesAsyncMethod)); 551 | 552 | [Test] 553 | public async Task Default_BytesWritten() 554 | { 555 | var bytes = new byte[10000]; 556 | var random = new Random(); 557 | random.NextBytes(bytes); 558 | 559 | var path = Path.Combine(writeAllBytesTestFolder, nameof(Default_BytesWritten)); 560 | Directory.CreateDirectory(writeAllBytesTestFolder); 561 | 562 | await AsyncFile.WriteAllBytesAsync(path, bytes).ConfigureAwait(false); 563 | 564 | var result = File.ReadAllBytes(path); 565 | 566 | CollectionAssert.AreEqual(bytes, result); 567 | } 568 | 569 | [Test] 570 | public async Task CancellationToken_ExceptionThrown() 571 | { 572 | var bytes = new byte[100000]; 573 | var random = new Random(); 574 | random.NextBytes(bytes); 575 | 576 | var path = Path.Combine(writeAllBytesTestFolder, nameof(CancellationToken_ExceptionThrown)); 577 | Directory.CreateDirectory(writeAllBytesTestFolder); 578 | 579 | var tokenSource = new CancellationTokenSource(); 580 | tokenSource.Cancel(); 581 | Assert.ThrowsAsync( 582 | async () => await AsyncFile.WriteAllBytesAsync(path, bytes, tokenSource.Token).ConfigureAwait(false)); 583 | } 584 | } 585 | 586 | [TestFixture] 587 | public class WriteAllLinesAsyncMethod 588 | { 589 | private readonly string writeAllLinesTestFolder = Path.Combine(FileTestFolder, nameof(WriteAllLinesAsyncMethod)); 590 | 591 | [Test] 592 | public async Task Default_LinesAppended() 593 | { 594 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 595 | var path = Path.Combine(writeAllLinesTestFolder, nameof(Default_LinesAppended)); 596 | 597 | Directory.CreateDirectory(writeAllLinesTestFolder); 598 | 599 | await AsyncFile.WriteAllLinesAsync(path, contents); 600 | 601 | var result = File.ReadAllLines(path); 602 | 603 | CollectionAssert.AreEqual(contents, result); 604 | } 605 | 606 | [TestCaseSource(typeof(FileTests), nameof(encodings))] 607 | public async Task WriteAllLinesWithEncoding(Encoding encoding) 608 | { 609 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 610 | var path = Path.Combine(writeAllLinesTestFolder, nameof(WriteAllLinesWithEncoding)); 611 | 612 | Directory.CreateDirectory(writeAllLinesTestFolder); 613 | 614 | await AsyncFile.WriteAllLinesAsync(path, contents, encoding); 615 | 616 | var result = File.ReadAllLines(path, encoding); 617 | 618 | CollectionAssert.AreEqual(contents, result); 619 | } 620 | 621 | [Test] 622 | public void CancellationToken_LinesAppendedAndExceptionThrown() 623 | { 624 | var contents = Enumerable.Repeat("This is a test line.", 30000).ToList(); 625 | var path = Path.Combine(writeAllLinesTestFolder, nameof(CancellationToken_LinesAppendedAndExceptionThrown)); 626 | Directory.CreateDirectory(writeAllLinesTestFolder); 627 | 628 | var tokenSource = new CancellationTokenSource(); 629 | Assert.ThrowsAsync(async () => 630 | { 631 | var task = AsyncFile.WriteAllLinesAsync(path, contents, tokenSource.Token); 632 | tokenSource.Cancel(); 633 | await task; 634 | }); 635 | 636 | var result = File.ReadAllLines(path); 637 | 638 | Assert.IsTrue(contents.Count > result.Length); 639 | } 640 | 641 | [Test] 642 | public void NullContent_ExceptionThrown() 643 | { 644 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 645 | var path = Path.Combine(writeAllLinesTestFolder, nameof(NullContent_ExceptionThrown)); 646 | 647 | Directory.CreateDirectory(writeAllLinesTestFolder); 648 | 649 | Assert.ThrowsAsync(async () => await AsyncFile.WriteAllLinesAsync(path, null)); 650 | } 651 | 652 | [Test] 653 | public async Task WriteAllLinesAsync_NullEncoding_ExceptionThrown() 654 | { 655 | var contents = Enumerable.Repeat("This is a test line.", 150).ToList(); 656 | var path = Path.Combine(writeAllLinesTestFolder, nameof(NullContent_ExceptionThrown)); 657 | 658 | Directory.CreateDirectory(writeAllLinesTestFolder); 659 | 660 | Assert.ThrowsAsync(async () => await AsyncFile.WriteAllLinesAsync(path, contents, null)); 661 | } 662 | } 663 | 664 | [TestFixture] 665 | public class WriteAllTextAsyncMethod 666 | { 667 | private readonly string writeAllTextTestFolder = Path.Combine(FileTestFolder, nameof(WriteAllTextAsyncMethod)); 668 | 669 | [Test] 670 | public async Task Default_TextAppended() 671 | { 672 | var contents = string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 673 | var path = Path.Combine(writeAllTextTestFolder, nameof(Default_TextAppended)); 674 | 675 | Directory.CreateDirectory(writeAllTextTestFolder); 676 | 677 | await AsyncFile.WriteAllTextAsync(path, contents); 678 | 679 | var result = File.ReadAllText(path); 680 | 681 | Assert.AreEqual(contents, result); 682 | } 683 | 684 | [TestCaseSource(typeof(FileTests), nameof(encodings))] 685 | public async Task WriteAllTextWithEncoding(Encoding encoding) 686 | { 687 | var contents = string.Join(Environment.NewLine, Enumerable.Repeat("This is a test line.", 150)); 688 | var path = Path.Combine(writeAllTextTestFolder, nameof(WriteAllTextWithEncoding)); 689 | 690 | Directory.CreateDirectory(writeAllTextTestFolder); 691 | 692 | await AsyncFile.WriteAllTextAsync(path, contents, encoding); 693 | 694 | var result = File.ReadAllText(path, encoding); 695 | 696 | Assert.AreEqual(contents, result); 697 | } 698 | 699 | [Test] 700 | public void NullContent_ExceptionThrown() 701 | { 702 | var path = Path.Combine(writeAllTextTestFolder, nameof(NullContent_ExceptionThrown)); 703 | 704 | Directory.CreateDirectory(writeAllTextTestFolder); 705 | 706 | Assert.ThrowsAsync(async () => await AsyncFile.WriteAllTextAsync(path, null)); 707 | } 708 | 709 | [Test] 710 | public void WriteAllTextAsync_NullEncoding_ExceptionThrown() 711 | { 712 | const string content = "This is a test line."; 713 | var path = Path.Combine(writeAllTextTestFolder, nameof(NullContent_ExceptionThrown)); 714 | 715 | Directory.CreateDirectory(writeAllTextTestFolder); 716 | 717 | Assert.ThrowsAsync(async () => await AsyncFile.WriteAllTextAsync(path, content, null)); 718 | } 719 | } 720 | } 721 | } -------------------------------------------------------------------------------- /AsyncIO.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("AsyncIO.Tests")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("2a6b24e4-96d0-408f-9508-d7918a41ea45")] 20 | -------------------------------------------------------------------------------- /AsyncIO.Tests/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | 4 | "dependencies": { 5 | "AsyncIO": "1.3-*", 6 | "dotnet-test-nunit": "3.4.0-beta-3", 7 | "NETStandard.Library": "1.6.1", 8 | "NUnit": "3.6.1" 9 | }, 10 | "testRunner": "nunit", 11 | "frameworks": { 12 | "netcoreapp1.1": { 13 | "imports": [ 14 | "netcoreapp1.1", 15 | "portable-net45+win8" 16 | ], 17 | "dependencies": { 18 | "Microsoft.NETCore.App": { 19 | "version": "1.1.0-*", 20 | "type": "platform" 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /AsyncIO.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AsyncIO", "AsyncIO\AsyncIO.xproj", "{F42882C7-40D2-473E-B910-0C0587178CC9}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ACEE45AB-F33D-4D70-A650-056F721722E5}" 9 | ProjectSection(SolutionItems) = preProject 10 | global.json = global.json 11 | EndProjectSection 12 | EndProject 13 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EEABDE18-096B-4E02-B82B-B3069FF78D54}" 14 | EndProject 15 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AsyncIO.Tests", "AsyncIO.Tests\AsyncIO.Tests.xproj", "{2A6B24E4-96D0-408F-9508-D7918A41EA45}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Release|Any CPU = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {F42882C7-40D2-473E-B910-0C0587178CC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {F42882C7-40D2-473E-B910-0C0587178CC9}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {F42882C7-40D2-473E-B910-0C0587178CC9}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {F42882C7-40D2-473E-B910-0C0587178CC9}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {2A6B24E4-96D0-408F-9508-D7918A41EA45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {2A6B24E4-96D0-408F-9508-D7918A41EA45}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {2A6B24E4-96D0-408F-9508-D7918A41EA45}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {2A6B24E4-96D0-408F-9508-D7918A41EA45}.Release|Any CPU.Build.0 = Release|Any CPU 31 | EndGlobalSection 32 | GlobalSection(SolutionProperties) = preSolution 33 | HideSolutionNode = FALSE 34 | EndGlobalSection 35 | GlobalSection(NestedProjects) = preSolution 36 | {F42882C7-40D2-473E-B910-0C0587178CC9} = {EEABDE18-096B-4E02-B82B-B3069FF78D54} 37 | {2A6B24E4-96D0-408F-9508-D7918A41EA45} = {EEABDE18-096B-4E02-B82B-B3069FF78D54} 38 | EndGlobalSection 39 | EndGlobal 40 | -------------------------------------------------------------------------------- /AsyncIO.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | <?xml version="1.0" encoding="utf-16"?><Profile name="File Layout"><CSReorderTypeMembers>True</CSReorderTypeMembers><CSArrangeQualifiers>True</CSArrangeQualifiers></Profile> 4 | <?xml version="1.0" encoding="utf-16"?><Profile name="MyCleanup"><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSArrangeQualifiers>True</CSArrangeQualifiers><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSReorderTypeMembers>True</CSReorderTypeMembers></Profile> 5 | File Layout 6 | File Layout 7 | True 8 | True 9 | True 10 | True 11 | True 12 | True 13 | True 14 | True 15 | True 16 | True 17 | True 18 | TOGETHER 19 | True 20 | True 21 | True 22 | LINE_BREAK 23 | True 24 | False 25 | True 26 | 150 27 | WRAP_IF_LONG 28 | <?xml version="1.0" encoding="utf-16"?> 29 | <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> 30 | <TypePattern DisplayName="COM interfaces or structs"> 31 | <TypePattern.Match> 32 | <Or> 33 | <And> 34 | <Kind Is="Interface" /> 35 | <Or> 36 | <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /> 37 | <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> 38 | </Or> 39 | </And> 40 | <HasAttribute Name="System.Runtime.InteropServices.StructLayoutAttribute" /> 41 | </Or> 42 | </TypePattern.Match> 43 | </TypePattern> 44 | <TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"> 45 | <TypePattern.Match> 46 | <And> 47 | <Kind Is="Class" /> 48 | <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" /> 49 | </And> 50 | </TypePattern.Match> 51 | <Entry DisplayName="Setup/Teardown Methods"> 52 | <Entry.Match> 53 | <And> 54 | <Kind Is="Method" /> 55 | <Or> 56 | <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" /> 57 | <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" /> 58 | <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" /> 59 | <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" /> 60 | </Or> 61 | </And> 62 | </Entry.Match> 63 | </Entry> 64 | <Entry DisplayName="All other members" /> 65 | <Entry DisplayName="Test Methods" Priority="100"> 66 | <Entry.Match> 67 | <And> 68 | <Kind Is="Method" /> 69 | <HasAttribute Name="NUnit.Framework.TestAttribute" /> 70 | </And> 71 | </Entry.Match> 72 | <Entry.SortBy> 73 | <Name /> 74 | </Entry.SortBy> 75 | </Entry> 76 | </TypePattern> 77 | <TypePattern DisplayName="Default Pattern"> 78 | <Region Name="Delegates"> 79 | <Entry DisplayName="Public Delegates" Priority="100"> 80 | <Entry.Match> 81 | <And> 82 | <Access Is="Public" /> 83 | <Kind Is="Delegate" /> 84 | </And> 85 | </Entry.Match> 86 | <Entry.SortBy> 87 | <Access /> 88 | </Entry.SortBy> 89 | </Entry> 90 | </Region> 91 | <Region Name="Enums"> 92 | <Entry DisplayName="Public Enums" Priority="100"> 93 | <Entry.Match> 94 | <And> 95 | <Access Is="Public" /> 96 | <Kind Is="Enum" /> 97 | </And> 98 | </Entry.Match> 99 | <Entry.SortBy> 100 | <Access /> 101 | </Entry.SortBy> 102 | </Entry> 103 | </Region> 104 | <Region Name="Static Fields and Constants"> 105 | <Entry DisplayName="Static Fields and Constants"> 106 | <Entry.Match> 107 | <Or> 108 | <Kind Is="Constant" /> 109 | <And> 110 | <Kind Is="Field" /> 111 | <Static /> 112 | </And> 113 | </Or> 114 | </Entry.Match> 115 | <Entry.SortBy> 116 | <Kind Is="Member" /> 117 | <Access /> 118 | <Readonly /> 119 | </Entry.SortBy> 120 | </Entry> 121 | </Region> 122 | <Region Name="Fields"> 123 | <Entry DisplayName="Fields"> 124 | <Entry.Match> 125 | <And> 126 | <Kind Is="Field" /> 127 | <Not> 128 | <Static /> 129 | </Not> 130 | </And> 131 | </Entry.Match> 132 | <Entry.SortBy> 133 | <Access /> 134 | <Readonly /> 135 | <Kind Is="Member" /> 136 | </Entry.SortBy> 137 | </Entry> 138 | </Region> 139 | <Region Name="Properties, Indexers"> 140 | <Entry DisplayName="Properties, Indexers"> 141 | <Entry.Match> 142 | <Or> 143 | <Kind Is="Property" /> 144 | <Kind Is="Indexer" /> 145 | <Kind Is="Autoproperty" /> 146 | </Or> 147 | </Entry.Match> 148 | <Entry.SortBy> 149 | <Kind Is="Member" /> 150 | <Access /> 151 | <Virtual /> 152 | <Override /> 153 | </Entry.SortBy> 154 | </Entry> 155 | </Region> 156 | <Region Name="Constructors"> 157 | <Entry DisplayName="Constructors"> 158 | <Entry.Match> 159 | <Kind Is="Constructor" /> 160 | </Entry.Match> 161 | <Entry.SortBy> 162 | <Static /> 163 | <Access /> 164 | </Entry.SortBy> 165 | </Entry> 166 | </Region> 167 | <Region Name="Methods"> 168 | <Entry DisplayName="Methods"> 169 | <Entry.Match> 170 | <Kind Is="Method" /> 171 | </Entry.Match> 172 | <Entry.SortBy> 173 | <Access /> 174 | <Static /> 175 | <Virtual /> 176 | <Override /> 177 | </Entry.SortBy> 178 | </Entry> 179 | </Region> 180 | <Region Name="Events"> 181 | <Entry DisplayName="Events"> 182 | <Entry.Match> 183 | <And> 184 | <Kind Is="Event" /> 185 | </And> 186 | </Entry.Match> 187 | <Entry.SortBy> 188 | <Access /> 189 | </Entry.SortBy> 190 | </Entry> 191 | </Region> 192 | <Region Name="${ImplementsInterface} Members" Priority="100"> 193 | <Region.GroupBy> 194 | <ImplementsInterface /> 195 | </Region.GroupBy> 196 | <Entry DisplayName="Interface Implementations" Priority="100"> 197 | <Entry.Match> 198 | <And> 199 | <Kind Is="Member" /> 200 | <ImplementsInterface /> 201 | </And> 202 | </Entry.Match> 203 | <Entry.SortBy> 204 | <ImplementsInterface /> 205 | <Access /> 206 | </Entry.SortBy> 207 | </Entry> 208 | </Region> 209 | <Region Name="Other"> 210 | <Entry DisplayName="All other members"> 211 | <Entry.SortBy> 212 | <Access /> 213 | <Kind Is="Member" /> 214 | </Entry.SortBy> 215 | </Entry> 216 | </Region> 217 | <Region Name="Nested Types"> 218 | <Entry DisplayName="Nested Types"> 219 | <Entry.Match> 220 | <Kind Is="Type" /> 221 | </Entry.Match> 222 | <Entry.SortBy> 223 | <Access /> 224 | </Entry.SortBy> 225 | </Entry> 226 | </Region> 227 | </TypePattern> 228 | </Patterns> 229 | False 230 | True 231 | Const reference 232 | public 233 | False 234 | Getter and setter 235 | False 236 | Value 237 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 238 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 239 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 240 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 241 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 242 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 243 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 244 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 245 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 246 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 247 | <Policy Inspect="True" Prefix="set_" Suffix="" Style="aa_bb" /> 248 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 249 | <Policy Inspect="True" Prefix="" Suffix="_" Style="aa_bb" /> 250 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 251 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 252 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 253 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 254 | <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /> 255 | EF 256 | IO 257 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 258 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 259 | <Configurator><ConnectList><ConnectItem><LastConnectTicks>1431645791429</LastConnectTicks><HostParameters type="LocalHostParameters" /></ConnectItem></ConnectList></Configurator> 260 | False 261 | True 262 | Disabled 263 | False 264 | False 265 | 4000 266 | False 267 | False 268 | False 269 | False 270 | False 271 | False 272 | False 273 | False 274 | False 275 | False 276 | False 277 | False 278 | False 279 | False 280 | False 281 | False 282 | False 283 | False 284 | False 285 | False 286 | NewVersion 287 | True 288 | True 289 | True 290 | True 291 | True 292 | True 293 | 09/13/2015 15:12:07 294 | False 295 | VS 296 | 525 297 | False 298 | <data><AttributeFilter ClassMask="System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute" IsEnabled="True" /></data> 299 | 100 300 | True 301 | True 302 | [-54,-22](1024,768) 303 | CsharpFileLayout 304 | -70,-319 305 | 422 306 | 268.5 307 | 406,261 308 | 211 309 | 89.5 310 | False 311 | True 312 | False 313 | True 314 | 14 315 | C:\Users\Mikhaylo\AppData\Local\JetBrains\Shared\vAny\Sessions -------------------------------------------------------------------------------- /AsyncIO/AsyncIO.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | f42882c7-40d2-473e-b910-0c0587178cc9 11 | AsyncIO 12 | .\obj 13 | .\bin\ 14 | v4.5 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /AsyncIO/FileSystem/Extensions/FileInfoExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Security; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | #pragma warning disable 1573 9 | 10 | namespace AsyncIO.FileSystem.Extensions 11 | { 12 | /// 13 | /// Provides async extension method for . 14 | /// 15 | public static class FileInfoExtensions 16 | { 17 | #region AppendAllLinesAsync 18 | 19 | /// 20 | /// Appends lines asynchronously to a file, and then closes the file. 21 | /// If the specified file does not exist, this method creates a file, writes the specified lines to the file, and then closes the file. 22 | /// 23 | /// The lines to append to the file. 24 | /// is null. 25 | /// File path is invalid (for example, the directory doesn’t exist or it is on an unmapped drive). 26 | /// An I/O error occurred while opening the file. 27 | /// File path is in an invalid format. 28 | /// The caller does not have the required permission. 29 | /// File path specifies a file that is read-only. 30 | /// -or- 31 | /// This operation is not supported on the current platform. 32 | /// -or- 33 | /// File path is a directory. 34 | /// -or- 35 | /// The caller does not have the required permission. 36 | /// 37 | /// The method creates the file if it doesn’t exist, but it doesn't create new directories. Therefore, the value of the path parameter must contain existing directories. 38 | /// Task that represents asynchronous operation. 39 | public static Task AppendAllLinesAsync(this FileInfo fileInfo, IEnumerable contents) 40 | { 41 | return AsyncFile.AppendAllLinesAsync(fileInfo.FullName, contents); 42 | } 43 | 44 | /// 45 | /// Appends lines asynchronously to a file by using a specified encoding, and then closes the file. 46 | /// If the specified file does not exist, this method creates a file, writes the specified lines to the file, and then closes the file. 47 | /// 48 | /// The lines to append to the file. 49 | /// The character encoding to use. 50 | /// is null. 51 | /// File path is invalid (for example, the directory doesn’t exist or it is on an unmapped drive). 52 | /// An I/O error occurred while opening the file. 53 | /// File path is in an invalid format. 54 | /// The caller does not have the required permission. 55 | /// File path specifies a file that is read-only. 56 | /// -or- 57 | /// This operation is not supported on the current platform. 58 | /// -or- 59 | /// File path is a directory. 60 | /// -or- 61 | /// The caller does not have the required permission. 62 | /// 63 | /// The method creates the file if it doesn’t exist, but it doesn't create new directories. Therefore, the value of the path parameter must contain existing directories. 64 | /// Task that represents asynchronous operation. 65 | public static Task AppendAllLinesAsync(this FileInfo fileInfo, IEnumerable contents, Encoding encoding) 66 | { 67 | return AsyncFile.AppendAllLinesAsync(fileInfo.FullName, contents, encoding, CancellationToken.None); 68 | } 69 | 70 | /// 71 | /// Appends lines asynchronously to a file, and then closes the file, and monitors cancellation requests. 72 | /// If the specified file does not exist, this method creates a file, writes the specified lines to the file, and then closes the file. 73 | /// 74 | /// The lines to append to the file. 75 | /// Cancellation token. 76 | /// is null. 77 | /// File path is invalid (for example, the directory doesn’t exist or it is on an unmapped drive). 78 | /// An I/O error occurred while opening the file. 79 | /// File path is in an invalid format. 80 | /// The caller does not have the required permission. 81 | /// File path specifies a file that is read-only. 82 | /// -or- 83 | /// This operation is not supported on the current platform. 84 | /// -or- 85 | /// File path is a directory. 86 | /// -or- 87 | /// The caller does not have the required permission. 88 | /// 89 | /// The method creates the file if it doesn’t exist, but it doesn't create new directories. Therefore, the value of the path parameter must contain existing directories. 90 | /// Task that represents asynchronous operation. 91 | public static Task AppendAllLinesAsync(this FileInfo fileInfo, IEnumerable contents, CancellationToken cancellationToken) 92 | { 93 | return AsyncFile.AppendAllLinesAsync(fileInfo.FullName, contents, Encoding.UTF8, cancellationToken); 94 | } 95 | 96 | /// 97 | /// Appends lines asynchronously to a file by using a specified encoding, and then closes the file, and monitors cancellation requests. 98 | /// If the specified file does not exist, this method creates a file, writes the specified lines to the file, and then closes the file. 99 | /// 100 | /// The lines to append to the file. 101 | /// The character encoding to use. 102 | /// Cancellation token. 103 | /// is null. 104 | /// File path is invalid (for example, the directory doesn’t exist or it is on an unmapped drive). 105 | /// An I/O error occurred while opening the file. 106 | /// File path is in an invalid format. 107 | /// The caller does not have the required permission. 108 | /// File path specifies a file that is read-only. 109 | /// -or- 110 | /// This operation is not supported on the current platform. 111 | /// -or- 112 | /// File path is a directory. 113 | /// -or- 114 | /// The caller does not have the required permission. 115 | /// 116 | /// The method creates the file if it doesn’t exist, but it doesn't create new directories. Therefore, the value of the path parameter must contain existing directories. 117 | /// Task that represents asynchronous operation. 118 | public static Task AppendAllLinesAsync(this FileInfo fileInfo, IEnumerable contents, Encoding encoding, 119 | CancellationToken cancellationToken) 120 | { 121 | return AsyncFile.AppendAllLinesAsync(fileInfo.FullName, contents, encoding, cancellationToken); 122 | } 123 | 124 | #endregion 125 | 126 | #region AppendAllTextAsync 127 | 128 | /// 129 | /// Asynchronously appends the specified string to the file, creating the file if it does not already exist. 130 | /// 131 | /// The string to append to the file. 132 | /// 133 | /// Given a string and a file path, this method opens the specified file, appends the string to the end of the file using the specified encoding, and then closes the file. The file handle is guaranteed to be closed by this method, even if exceptions are raised. 134 | /// The method creates the file if it doesn’t exist, but it doesn't create new directories. Therefore, the value of the path parameter must contain existing directories. 135 | /// 136 | /// File path is a zero-length string, contains only white space, or contains one more invalid characters defined by the method. 137 | /// is null. 138 | /// File path is invalid (for example, the directory doesn’t exist or it is on an unmapped drive). 139 | /// An I/O error occurred while opening the file. 140 | /// File path is in an invalid format. 141 | /// File path exceeds the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters and file names must be less than 260 characters. 142 | /// The caller does not have the required permission. 143 | /// File path specifies a file that is read-only. 144 | /// -or- 145 | /// This operation is not supported on the current platform. 146 | /// -or- 147 | /// File path is a directory. 148 | /// -or- 149 | /// The caller does not have the required permission. 150 | /// 151 | /// Task that represents asynchronous operation. 152 | public static Task AppendAllTextAsync(this FileInfo fileInfo, string contents) 153 | { 154 | return AsyncFile.AppendAllTextAsync(fileInfo.FullName, contents, Encoding.UTF8); 155 | } 156 | 157 | /// 158 | /// Asynchronously appends the specified string to the file, creating the file if it does not already exist. 159 | /// 160 | /// The string to append to the file. 161 | /// The character encoding to use. 162 | /// 163 | /// Given a string and a file path, this method opens the specified file, appends the string to the end of the file using the specified encoding, and then closes the file. The file handle is guaranteed to be closed by this method, even if exceptions are raised. 164 | /// The method creates the file if it doesn’t exist, but it doesn't create new directories. Therefore, the value of the path parameter must contain existing directories. 165 | /// 166 | /// File path is a zero-length string, contains only white space, or contains one more invalid characters defined by the method. 167 | /// is null. 168 | /// File path is invalid (for example, the directory doesn’t exist or it is on an unmapped drive). 169 | /// An I/O error occurred while opening the file. 170 | /// File path is in an invalid format. 171 | /// File path exceeds the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters and file names must be less than 260 characters. 172 | /// The caller does not have the required permission. 173 | /// File path specifies a file that is read-only. 174 | /// -or- 175 | /// This operation is not supported on the current platform. 176 | /// -or- 177 | /// File path is a directory. 178 | /// -or- 179 | /// The caller does not have the required permission. 180 | /// 181 | /// Task that represents asynchronous operation. 182 | public static Task AppendAllTextAsync(this FileInfo fileInfo, string contents, Encoding encoding) 183 | { 184 | return AsyncFile.AppendAllTextAsync(fileInfo.FullName, contents, encoding); 185 | } 186 | 187 | #endregion 188 | 189 | #region CopyToAsync 190 | 191 | /// 192 | /// Asynchronously copies an existing file to a new file, and monitors cancellation requests. Overwriting a file of the same name is not allowed. 193 | /// 194 | /// 195 | /// The name of the destination file. This cannot be a directory. 196 | /// 197 | /// 198 | /// The parameter can specify relative or absolute path information. 199 | /// Relative path information is interpreted as relative to the current working directory. 200 | /// This method does not support wildcard characters in the parameters. 201 | /// 202 | /// The attributes of the original file are retained in the copied file. 203 | /// 204 | /// 205 | /// 206 | /// File path or is a zero-length string, contains only white space, or contains one more invalid characters defined by the method. 207 | /// -or- 208 | /// File path or specifies a directory. 209 | /// 210 | /// Either File path or is null. 211 | /// The path specified inFile path or is invalid (for example, it is on an unmapped drive). 212 | /// 213 | /// exists. 214 | /// -or- 215 | /// An I/O error has occurred. 216 | /// 217 | /// 218 | /// The specified path, file name, or both exceed the system-defined maximum length. 219 | /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 220 | /// 221 | /// Source file was not found. 222 | /// The caller does not have the required permission. 223 | /// is read-only. 224 | /// -or- 225 | /// The caller does not have the required permission. 226 | /// 227 | /// 228 | /// Task that represents asynchronous operation. 229 | public static Task CopyToAsync(this FileInfo fileInfo, string destFileName) 230 | { 231 | return AsyncFile.CopyAsync(fileInfo.FullName, destFileName); 232 | } 233 | 234 | /// 235 | /// Asynchronously copies an existing file to a new file, and monitors cancellation requests. Overwriting a file of the same name is not allowed. 236 | /// 237 | /// 238 | /// The name of the destination file. This cannot be a directory. 239 | /// true if the destination file can be overwritten; otherwise, false. 240 | /// 241 | /// 242 | /// The parameter can specify relative or absolute path information. 243 | /// Relative path information is interpreted as relative to the current working directory. 244 | /// This method does not support wildcard characters in the parameters. 245 | /// 246 | /// The attributes of the original file are retained in the copied file. 247 | /// 248 | /// 249 | /// 250 | /// File path or is a zero-length string, contains only white space, or contains one more invalid characters defined by the method. 251 | /// -or- 252 | /// File path or specifies a directory. 253 | /// 254 | /// Either File path or is null. 255 | /// The path specified inFile path or is invalid (for example, it is on an unmapped drive). 256 | /// 257 | /// exists. 258 | /// -or- 259 | /// An I/O error has occurred. 260 | /// 261 | /// 262 | /// The specified path, file name, or both exceed the system-defined maximum length. 263 | /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 264 | /// 265 | /// Source file was not found. 266 | /// The caller does not have the required permission. 267 | /// is read-only. 268 | /// -or- 269 | /// The caller does not have the required permission. 270 | /// 271 | /// 272 | /// Task that represents asynchronous operation. 273 | public static Task CopyToAsync(this FileInfo fileInfo, string destFileName, bool overwrite) 274 | { 275 | return AsyncFile.CopyAsync(fileInfo.FullName, destFileName, overwrite); 276 | } 277 | 278 | /// 279 | /// Asynchronously copies an existing file to a new file, and monitors cancellation requests. Overwriting a file of the same name is not allowed. 280 | /// 281 | /// 282 | /// The name of the destination file. This cannot be a directory. 283 | /// Cancellation token. 284 | /// 285 | /// 286 | /// The parameter can specify relative or absolute path information. 287 | /// Relative path information is interpreted as relative to the current working directory. 288 | /// This method does not support wildcard characters in the parameters. 289 | /// 290 | /// The attributes of the original file are retained in the copied file. 291 | /// 292 | /// 293 | /// 294 | /// File path or is a zero-length string, contains only white space, or contains one more invalid characters defined by the method. 295 | /// -or- 296 | /// File path or specifies a directory. 297 | /// 298 | /// Either File path or is null. 299 | /// The path specified inFile path or is invalid (for example, it is on an unmapped drive). 300 | /// 301 | /// exists. 302 | /// -or- 303 | /// An I/O error has occurred. 304 | /// 305 | /// 306 | /// The specified path, file name, or both exceed the system-defined maximum length. 307 | /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 308 | /// 309 | /// Source file was not found. 310 | /// The caller does not have the required permission. 311 | /// is read-only. 312 | /// -or- 313 | /// The caller does not have the required permission. 314 | /// 315 | /// 316 | /// Task that represents asynchronous operation. 317 | public static Task CopyToAsync(this FileInfo fileInfo, string destFileName, CancellationToken cancellationToken) 318 | { 319 | return AsyncFile.CopyAsync(fileInfo.FullName, destFileName, cancellationToken); 320 | } 321 | 322 | /// 323 | /// Asynchronously copies an existing file to a new file, and monitors cancellation requests. Overwriting a file of the same name is not allowed. 324 | /// 325 | /// 326 | /// The name of the destination file. This cannot be a directory. 327 | /// true if the destination file can be overwritten; otherwise, false. 328 | /// Cancellation token. 329 | /// 330 | /// 331 | /// The parameter can specify relative or absolute path information. 332 | /// Relative path information is interpreted as relative to the current working directory. 333 | /// This method does not support wildcard characters in the parameters. 334 | /// 335 | /// The attributes of the original file are retained in the copied file. 336 | /// 337 | /// 338 | /// 339 | /// File path or is a zero-length string, contains only white space, or contains one more invalid characters defined by the method. 340 | /// -or- 341 | /// File path or specifies a directory. 342 | /// 343 | /// Either File path or is null. 344 | /// The path specified inFile path or is invalid (for example, it is on an unmapped drive). 345 | /// 346 | /// exists. 347 | /// -or- 348 | /// An I/O error has occurred. 349 | /// 350 | /// 351 | /// The specified path, file name, or both exceed the system-defined maximum length. 352 | /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 353 | /// 354 | /// Source file was not found. 355 | /// The caller does not have the required permission. 356 | /// is read-only. 357 | /// -or- 358 | /// The caller does not have the required permission. 359 | /// 360 | /// 361 | /// Task that represents asynchronous operation. 362 | public static Task CopyToAsync(this FileInfo fileInfo, string destFileName, bool overwrite, CancellationToken cancellationToken) 363 | { 364 | return AsyncFile.CopyAsync(fileInfo.FullName, destFileName, overwrite, cancellationToken); 365 | } 366 | 367 | #endregion 368 | 369 | #region DeleteAsync 370 | 371 | /// 372 | /// Asynchronously deletes the specified file. 373 | /// 374 | /// 375 | /// 376 | /// If the file to be deleted does not exist, no exception is thrown. 377 | /// 378 | /// 379 | /// File path is a zero-length string, contains only white space, or contains one more invalid characters defined by the method. 380 | /// File path is null. 381 | /// The path specified in File path is invalid (for example, it is on an unmapped drive). 382 | /// 383 | /// The specified file is in use. 384 | /// -or- 385 | /// There is an open handle on the file, and the operating system is Windows XP or earlier. This open handle can result from enumerating directories and files. 386 | /// 387 | /// File path is in an invalid format. 388 | /// 389 | /// The specified path, file name, or both exceed the system-defined maximum length. 390 | /// For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 391 | /// 392 | /// The caller does not have the required permission. 393 | /// File path specifies a read-only file. 394 | /// -or- 395 | /// The caller does not have the required permission. 396 | /// -or- 397 | /// The file is an executable file that is in use. 398 | /// 399 | /// 400 | /// Task that represents asynchronous operation. 401 | public static Task DeleteAsync(this FileInfo fileInfo) 402 | { 403 | return AsyncFile.DeleteAsync(fileInfo.FullName); 404 | } 405 | 406 | #endregion 407 | 408 | #region ReadAllBytesAsync 409 | 410 | /// 411 | /// Opens a binary file, asynchronously reads the contents of the file into a byte array, and then closes the file. 412 | /// 413 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 414 | /// File path is null. 415 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 416 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 417 | /// An I/O error occurred while opening the file. 418 | /// 419 | /// This operation is not supported on the current platform. 420 | /// -or- 421 | /// The caller does not have the required permission. 422 | /// 423 | /// The file specified in File path was not found. 424 | /// File path is in an invalid format. 425 | /// The caller does not have the required permission. 426 | /// 427 | /// A task with a byte array containing the contents of the file. 428 | public static Task ReadAllBytesAsync(this FileInfo fileInfo) 429 | { 430 | return AsyncFile.ReadAllBytesAsync(fileInfo.FullName); 431 | } 432 | 433 | /// 434 | /// Opens a binary file, asynchronously reads the contents of the file into a byte array, and then closes the file. 435 | /// 436 | /// The cancellation token. 437 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 438 | /// File path is null. 439 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 440 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 441 | /// An I/O error occurred while opening the file. 442 | /// 443 | /// This operation is not supported on the current platform. 444 | /// -or- 445 | /// The caller does not have the required permission. 446 | /// 447 | /// The file specified in File path was not found. 448 | /// File path is in an invalid format. 449 | /// The caller does not have the required permission. 450 | /// 451 | /// A task with a byte array containing the contents of the file. 452 | public static Task ReadAllBytesAsync(this FileInfo fileInfo, CancellationToken cancellationToken) 453 | { 454 | return AsyncFile.ReadAllBytesAsync(fileInfo.FullName, cancellationToken); 455 | } 456 | 457 | #endregion 458 | 459 | #region ReadAllLinesAsync 460 | 461 | /// 462 | /// Opens a file, asynchronously reads all lines of the file, and then closes the file. 463 | /// 464 | /// 465 | /// A task with a string array containing all lines of the file. 466 | /// 467 | /// 468 | /// 469 | /// This method opens a file, reads each line of the file, and then adds each line as an element of a string array. It then closes the file. 470 | /// A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. 471 | /// The resulting string does not contain the terminating carriage return and/or line feed. 472 | /// 473 | /// 474 | /// 475 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 476 | /// File path is null. 477 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 478 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 479 | /// An I/O error occurred while opening the file. 480 | /// 481 | /// File path specified a file that is read-only. 482 | /// -or- 483 | /// This operation is not supported on the current platform. 484 | /// -or- 485 | /// The caller does not have the required permission. 486 | /// 487 | /// The file specified in File path was not found. 488 | /// File path is in an invalid format. 489 | /// The caller does not have the required permission. 490 | public static Task ReadAllLinesAsync(this FileInfo fileInfo) 491 | { 492 | return AsyncFile.ReadAllLinesAsync(fileInfo.FullName); 493 | } 494 | 495 | /// 496 | /// Opens a file, asynchronously reads all lines of the file, and then closes the file. 497 | /// 498 | /// 499 | /// The encoding applied to the contents of the file. 500 | /// 501 | /// A task with a string array containing all lines of the file. 502 | /// 503 | /// 504 | /// 505 | /// This method opens a file, reads each line of the file, and then adds each line as an element of a string array. It then closes the file. 506 | /// A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. 507 | /// The resulting string does not contain the terminating carriage return and/or line feed. 508 | /// 509 | /// 510 | /// 511 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 512 | /// File path is null. 513 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 514 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 515 | /// An I/O error occurred while opening the file. 516 | /// 517 | /// File path specified a file that is read-only. 518 | /// -or- 519 | /// This operation is not supported on the current platform. 520 | /// -or- 521 | /// The caller does not have the required permission. 522 | /// 523 | /// The file specified in File path was not found. 524 | /// File path is in an invalid format. 525 | /// The caller does not have the required permission. 526 | public static Task ReadAllLinesAsync(this FileInfo fileInfo, Encoding encoding) 527 | { 528 | return AsyncFile.ReadAllLinesAsync(fileInfo.FullName, encoding); 529 | } 530 | 531 | /// 532 | /// Opens a file, asynchronously reads all lines of the file, and then closes the file. 533 | /// 534 | /// 535 | /// The cancellation token. 536 | /// 537 | /// A task with a string array containing all lines of the file. 538 | /// 539 | /// 540 | /// 541 | /// This method opens a file, reads each line of the file, and then adds each line as an element of a string array. It then closes the file. 542 | /// A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. 543 | /// The resulting string does not contain the terminating carriage return and/or line feed. 544 | /// 545 | /// 546 | /// 547 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 548 | /// File path is null. 549 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 550 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 551 | /// An I/O error occurred while opening the file. 552 | /// 553 | /// File path specified a file that is read-only. 554 | /// -or- 555 | /// This operation is not supported on the current platform. 556 | /// -or- 557 | /// The caller does not have the required permission. 558 | /// 559 | /// The file specified in File path was not found. 560 | /// File path is in an invalid format. 561 | /// The caller does not have the required permission. 562 | public static Task ReadAllLinesAsync(this FileInfo fileInfo, CancellationToken cancellationToken) 563 | { 564 | return AsyncFile.ReadAllLinesAsync(fileInfo.FullName, cancellationToken); 565 | } 566 | 567 | /// 568 | /// Opens a file, asynchronously reads all lines of the file, and then closes the file. 569 | /// 570 | /// 571 | /// The encoding applied to the contents of the file. 572 | /// The cancellation token. 573 | /// 574 | /// A task with a string array containing all lines of the file. 575 | /// 576 | /// 577 | /// 578 | /// This method opens a file, reads each line of the file, and then adds each line as an element of a string array. It then closes the file. 579 | /// A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. 580 | /// The resulting string does not contain the terminating carriage return and/or line feed. 581 | /// 582 | /// 583 | /// 584 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 585 | /// File path is null. 586 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 587 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 588 | /// An I/O error occurred while opening the file. 589 | /// 590 | /// File path specified a file that is read-only. 591 | /// -or- 592 | /// This operation is not supported on the current platform. 593 | /// -or- 594 | /// The caller does not have the required permission. 595 | /// 596 | /// The file specified in File path was not found. 597 | /// File path is in an invalid format. 598 | /// The caller does not have the required permission. 599 | public static Task ReadAllLinesAsync(this FileInfo fileInfo, Encoding encoding, CancellationToken cancellationToken) 600 | { 601 | return AsyncFile.ReadAllLinesAsync(fileInfo.FullName, encoding, cancellationToken); 602 | } 603 | 604 | #endregion 605 | 606 | #region ReadAllTextAsync 607 | 608 | /// 609 | /// Opens a file, asynchronously reads all lines of the file, and then closes the file. 610 | /// 611 | /// 612 | /// A task with a string containing all lines of the file. 613 | /// 614 | /// 615 | /// 616 | /// This method opens a file, reads each line of the file, and then adds each line as an element of a string. It then closes the file. 617 | /// A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. 618 | /// The resulting string does not contain the terminating carriage return and/or line feed. 619 | /// 620 | /// The file handle is guaranteed to be closed by this method, even if exceptions are raised. 621 | /// 622 | /// 623 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 624 | /// File path is null. 625 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 626 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 627 | /// An I/O error occurred while opening the file. 628 | /// 629 | /// File path specified a file that is read-only. 630 | /// -or- 631 | /// This operation is not supported on the current platform. 632 | /// -or- 633 | /// The caller does not have the required permission. 634 | /// 635 | /// The file specified in File path was not found. 636 | /// File path is in an invalid format. 637 | /// The caller does not have the required permission. 638 | public static Task ReadAllTextAsync(this FileInfo fileInfo) 639 | { 640 | return AsyncFile.ReadAllTextAsync(fileInfo.FullName); 641 | } 642 | 643 | /// 644 | /// Opens a file, asynchronously reads all lines of the file, and then closes the file. 645 | /// 646 | /// 647 | /// The encoding applied to the contents of the file. 648 | /// 649 | /// A task with a string containing all lines of the file. 650 | /// 651 | /// 652 | /// 653 | /// This method opens a file, reads each line of the file, and then adds each line as an element of a string. It then closes the file. 654 | /// A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. 655 | /// The resulting string does not contain the terminating carriage return and/or line feed. 656 | /// 657 | /// The file handle is guaranteed to be closed by this method, even if exceptions are raised. 658 | /// 659 | /// 660 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 661 | /// File path is null. 662 | /// The specified path, file name, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 663 | /// The path specified in File path is invalid, (dor example, it is on an unmapped drive). 664 | /// An I/O error occurred while opening the file. 665 | /// 666 | /// File path specified a file that is read-only. 667 | /// -or- 668 | /// This operation is not supported on the current platform. 669 | /// -or- 670 | /// The caller does not have the required permission. 671 | /// 672 | /// The file specified in File path was not found. 673 | /// File path is in an invalid format. 674 | /// The caller does not have the required permission. 675 | public static Task ReadAllTextAsync(this FileInfo fileInfo, Encoding encoding) 676 | { 677 | return AsyncFile.ReadAllTextAsync(fileInfo.FullName, encoding); 678 | } 679 | 680 | #endregion 681 | 682 | #region WriteAllBytesAsync 683 | 684 | /// 685 | /// Creates a new file, asynchronously writes the specified byte array to the file, and then closes the file. 686 | /// If the target file already exists, it is overwritten. 687 | /// 688 | /// 689 | /// The bytes to write to the file. 690 | /// 691 | /// Task that represents asynchronous operation. 692 | /// 693 | /// Given a byte array, this method opens the specified file, writes the contents of the byte array to the file, and then closes the file. 694 | /// 695 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 696 | /// File path or is null 697 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 698 | /// The specified path is invalid (for example, it is on an unmapped drive). 699 | /// An I/O error occurred while opening the file. 700 | /// 701 | /// File path specified a file that is read-only. 702 | /// -or- 703 | /// This operation is not supported on the current platform. 704 | /// -or- 705 | /// The caller does not have the required permission. 706 | /// 707 | /// File path is in an invalid format. 708 | /// The caller does not have the required permission. 709 | public static Task WriteAllBytesAsync(this FileInfo fileInfo, byte[] bytes) 710 | { 711 | return AsyncFile.WriteAllBytesAsync(fileInfo.FullName, bytes); 712 | } 713 | 714 | /// 715 | /// Creates a new file, asynchronously writes the specified byte array to the file, and then closes the file. 716 | /// If the target file already exists, it is overwritten. 717 | /// 718 | /// 719 | /// The bytes to write to the file. 720 | /// The cancellation token. 721 | /// 722 | /// Task that represents asynchronous operation. 723 | /// 724 | /// Given a byte array, this method opens the specified file, writes the contents of the byte array to the file, and then closes the file. 725 | /// 726 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 727 | /// File path or is null 728 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 729 | /// The specified path is invalid (for example, it is on an unmapped drive). 730 | /// An I/O error occurred while opening the file. 731 | /// 732 | /// File path specified a file that is read-only. 733 | /// -or- 734 | /// This operation is not supported on the current platform. 735 | /// -or- 736 | /// The caller does not have the required permission. 737 | /// 738 | /// File path is in an invalid format. 739 | /// The caller does not have the required permission. 740 | public static Task WriteAllBytesAsync(this FileInfo fileInfo, byte[] bytes, CancellationToken cancellationToken) 741 | { 742 | return AsyncFile.WriteAllBytesAsync(fileInfo.FullName, bytes, cancellationToken); 743 | } 744 | 745 | #endregion 746 | 747 | #region WriteAllLinesAsync 748 | 749 | /// 750 | /// Creates a new file, asynchronously writes a collection of strings to the file, and then closes the file. 751 | /// 752 | /// 753 | /// The lines to write to the file. 754 | /// 755 | /// Task that represents asynchronous operation. 756 | /// 757 | /// If the target file already exists, it is overwritten. 758 | /// 759 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 760 | /// File path or is null 761 | /// File path is invalid (for example, it is on an unmapped drive). 762 | /// An I/O error occurred while opening the file. 763 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 764 | /// File path is in an invalid format. 765 | /// The caller does not have the required permission. 766 | /// 767 | /// File path specified a file that is read-only. 768 | /// -or- 769 | /// This operation is not supported on the current platform. 770 | /// -or- 771 | /// The caller does not have the required permission. 772 | /// 773 | public static Task WriteAllLinesAsync(this FileInfo fileInfo, IEnumerable contents) 774 | { 775 | return AsyncFile.WriteAllLinesAsync(fileInfo.FullName, contents); 776 | } 777 | 778 | /// 779 | /// Creates a new file, asynchronously writes a collection of strings to the file, and then closes the file. 780 | /// 781 | /// 782 | /// The lines to write to the file. 783 | /// The character encoding to use. 784 | /// 785 | /// Task that represents asynchronous operation. 786 | /// 787 | /// If the target file already exists, it is overwritten. 788 | /// 789 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 790 | /// File path or is null 791 | /// File path is invalid (for example, it is on an unmapped drive). 792 | /// An I/O error occurred while opening the file. 793 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 794 | /// File path is in an invalid format. 795 | /// The caller does not have the required permission. 796 | /// 797 | /// File path specified a file that is read-only. 798 | /// -or- 799 | /// This operation is not supported on the current platform. 800 | /// -or- 801 | /// The caller does not have the required permission. 802 | /// 803 | public static Task WriteAllLinesAsync(this FileInfo fileInfo, IEnumerable contents, Encoding encoding) 804 | { 805 | return AsyncFile.WriteAllLinesAsync(fileInfo.FullName, contents, encoding); 806 | } 807 | 808 | /// 809 | /// Creates a new file, asynchronously writes a collection of strings to the file, and then closes the file. 810 | /// 811 | /// 812 | /// The lines to write to the file. 813 | /// The cancellation token. 814 | /// 815 | /// Task that represents asynchronous operation. 816 | /// 817 | /// If the target file already exists, it is overwritten. 818 | /// 819 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 820 | /// File path or is null 821 | /// File path is invalid (for example, it is on an unmapped drive). 822 | /// An I/O error occurred while opening the file. 823 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 824 | /// File path is in an invalid format. 825 | /// The caller does not have the required permission. 826 | /// 827 | /// File path specified a file that is read-only. 828 | /// -or- 829 | /// This operation is not supported on the current platform. 830 | /// -or- 831 | /// The caller does not have the required permission. 832 | /// 833 | public static Task WriteAllLinesAsync(this FileInfo fileInfo, IEnumerable contents, CancellationToken cancellationToken) 834 | { 835 | return AsyncFile.WriteAllLinesAsync(fileInfo.FullName, contents, cancellationToken); 836 | } 837 | 838 | /// 839 | /// Creates a new file, asynchronously writes a collection of strings to the file, and then closes the file. 840 | /// 841 | /// 842 | /// The lines to write to the file. 843 | /// The character encoding to use. 844 | /// The cancellation token. 845 | /// 846 | /// Task that represents asynchronous operation. 847 | /// 848 | /// If the target file already exists, it is overwritten. 849 | /// 850 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 851 | /// File path or is null 852 | /// File path is invalid (for example, it is on an unmapped drive). 853 | /// An I/O error occurred while opening the file. 854 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 855 | /// File path is in an invalid format. 856 | /// The caller does not have the required permission. 857 | /// 858 | /// File path specified a file that is read-only. 859 | /// -or- 860 | /// This operation is not supported on the current platform. 861 | /// -or- 862 | /// The caller does not have the required permission. 863 | /// 864 | public static Task WriteAllLinesAsync(this FileInfo fileInfo, IEnumerable contents, Encoding encoding, CancellationToken cancellationToken) 865 | { 866 | return AsyncFile.WriteAllLinesAsync(fileInfo.FullName, contents, encoding, cancellationToken); 867 | } 868 | 869 | #endregion 870 | 871 | #region WriteAllTextAsync 872 | 873 | /// 874 | /// Creates a new file, asynchronously writes the specified string to the file, and then closes the file. 875 | /// If the target file already exists, it is overwritten. 876 | /// 877 | /// 878 | /// The string to write to the file. 879 | /// 880 | /// Task that represents asynchronous operation. 881 | /// 882 | /// If the target file already exists, it is overwritten. 883 | /// 884 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 885 | /// File path or is null 886 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 887 | /// File path is invalid (for example, it is on an unmapped drive). 888 | /// An I/O error occurred while opening the file. 889 | /// File path is in an invalid format. 890 | /// The caller does not have the required permission. 891 | /// 892 | /// File path specified a file that is read-only. 893 | /// -or- 894 | /// This operation is not supported on the current platform. 895 | /// -or- 896 | /// The caller does not have the required permission. 897 | /// 898 | public static Task WriteAllTextAsync(this FileInfo fileInfo, string contents) 899 | { 900 | return AsyncFile.WriteAllTextAsync(fileInfo.FullName, contents); 901 | } 902 | 903 | /// 904 | /// Creates a new file, asynchronously writes the specified string to the file, and then closes the file. 905 | /// If the target file already exists, it is overwritten. 906 | /// 907 | /// 908 | /// The string to write to the file. 909 | /// The encoding to apply to the string. 910 | /// 911 | /// Task that represents asynchronous operation. 912 | /// 913 | /// If the target file already exists, it is overwritten. 914 | /// 915 | /// File path is a zero-length string, contains only white space, or contains invalid characters as defined in 916 | /// File path or is null 917 | /// The specified path, file name, or both exceed the system-defined maximum length.For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters. 918 | /// File path is invalid (for example, it is on an unmapped drive). 919 | /// An I/O error occurred while opening the file. 920 | /// File path is in an invalid format. 921 | /// The caller does not have the required permission. 922 | /// 923 | /// File path specified a file that is read-only. 924 | /// -or- 925 | /// This operation is not supported on the current platform. 926 | /// -or- 927 | /// The caller does not have the required permission. 928 | /// 929 | public static Task WriteAllTextAsync(this FileInfo fileInfo, string contents, Encoding encoding) 930 | { 931 | return AsyncFile.WriteAllTextAsync(fileInfo.FullName, contents, encoding); 932 | } 933 | 934 | #endregion 935 | } 936 | } -------------------------------------------------------------------------------- /AsyncIO/FileSystem/PathValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace AsyncIO.FileSystem 6 | { 7 | internal static class PathValidator 8 | { 9 | /// 10 | /// Ensures the correct file system path. 11 | /// 12 | /// The path to file or directory. 13 | /// is null 14 | /// is a zero-length string, contains only white space, or contains invalid characters as defined in 15 | /// Throws an exception if is not a correct file system path, otherwise no. 16 | internal static void EnsureCorrectFileSystemPath(string path) 17 | { 18 | if (path == null) 19 | throw new ArgumentNullException($"{nameof(path)} is null.", nameof(path)); 20 | 21 | if (string.IsNullOrWhiteSpace(path) || HasSpecifiedChars(path, Path.GetInvalidPathChars())) 22 | { 23 | var message = 24 | $"{nameof(path)} is a zero-length string, contains only white space, or contains one or more invalid characters as defined by InvalidPathChars."; 25 | throw new ArgumentException(message, nameof(path)); 26 | } 27 | } 28 | 29 | private static bool HasSpecifiedChars(string text, char[] chars) 30 | { 31 | var charsHashSet = new HashSet(chars); 32 | for (var i = 0; i < text.Length; ++i) 33 | { 34 | if (charsHashSet.Contains(text[i])) 35 | return true; 36 | } 37 | return false; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /AsyncIO/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("AsyncIO.DotNet")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("f42882c7-40d2-473e-b910-0c0587178cc9")] 20 | -------------------------------------------------------------------------------- /AsyncIO/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.3-*", 3 | 4 | "title": "AsyncIO.DotNet", 5 | "authors": [ 6 | "Mykhailo Matviiv" 7 | ], 8 | "description": 9 | "Easy-to-use library for common async IO file system operations. Implemented operations are fully asynchronous and do not use threads from thread pool.\nAsyncIO provides decent control over async execution (e.g. support of CancellationToken) and provides API for specifying encoding.", 10 | "packOptions": { 11 | "owners": [ 12 | "Mykhailo Matviiv" 13 | ], 14 | "summary": "Easy-to-use library for common asynchronous file system operations.", 15 | "licenseUrl": "https://github.com/FireNero/AsyncIO/blob/master/LICENSE", 16 | "projectUrl": "https://github.com/FireNero/AsyncIO", 17 | "tags": [ 18 | ".net c# async io file filesystem" 19 | ], 20 | "releaseNotes": "Implement async extension methods for FileInfo object.\nLower netstandard version to 1.3 from 1.6." 21 | }, 22 | "frameworks": { 23 | "netstandard1.3": { 24 | "imports": "dnxcore50", 25 | "dependencies": { 26 | "NETStandard.Library": "1.6.0" 27 | } 28 | }, 29 | "net45": { 30 | 31 | } 32 | }, 33 | "buildOptions": { 34 | "xmlDoc": true 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Mykhailo Matviiv 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AsyncIO 2 | 3 | AsyncIO is easy-to-use .NET library for common async IO file system operations. Implemented operations are fully asynchronous and do not use threads from thread pool. 4 | 5 | AsyncIO provides decent control over async execution (e.g. support of [`CancellationToken`](https://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken(v=vs.110).aspx)) and provides API for specifying [`Encoding`](https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx). 6 | 7 | ## Installation 8 | 9 | You can install AsyncIO from [nuget](https://www.nuget.org/packages/AsyncIO.DotNet/). 10 | 11 | Also, you can download compiled dll from the [releases page](https://github.com/FireNero/AsyncIO/releases). 12 | 13 | ## Usage 14 | 15 | AsyncIO is very easy to use especially if you used [`System.IO.File`](https://msdn.microsoft.com/en-us/library/system.io.file(v=vs.110).aspx). There is a static class `AsyncFile` to access all supported async io operations. 16 | You can also use extension methods for [`System.IO.FileInfo`](https://msdn.microsoft.com/en-us/library/system.io.fileinfo(v=vs.110).aspx). 17 | 18 | ### Examples 19 | 20 | * Read text from file 21 | 22 | ```csharp 23 | var text = await AsyncFile.ReadAllTextAsync("path_to_file"); 24 | ``` 25 | 26 | * Read text from file with Encoding 27 | 28 | ```csharp 29 | var text = await AsyncFile.ReadAllTextAsync("path_to_file", Encoding.UTF8); 30 | ``` 31 | 32 | * CancellationToken usage 33 | 34 | ```csharp 35 | var tokenSource = new CancellationTokenSource(); 36 | try 37 | { 38 | var moveTask = AsyncFile.MoveAsync("file_source_path", "file_destination_path", tokenSource.Token); 39 | tokenSource.Cancel(); 40 | await moveTask; 41 | } 42 | catch (OperationCancelledException e) 43 | { 44 | // Handle cancellation here. 45 | } 46 | ``` 47 | 48 | * [`System.IO.FileInfo`](https://msdn.microsoft.com/en-us/library/system.io.fileinfo(v=vs.110).aspx) extension method usage 49 | 50 | ```csharp 51 | var fileInfo = new FileInfo("path_to_file"); 52 | var text = await fileInfo.ReadAllTextAsync("path_to_file"); 53 | ``` 54 | 55 | ### Supported methods 56 | 57 | * AppendAllLinesAsync 58 | * AppendAllTextAsync 59 | * CopyAsync 60 | * DeleteAsync 61 | * MoveAsync 62 | * ReadAllBytesAsync 63 | * ReadAllLinesAsync 64 | * ReadAllTextAsync 65 | * WriteAllBytesAsync 66 | * WriteAllLinesAsync 67 | * WriteAllTextAsync 68 | 69 | ## Contribution 70 | 71 | ### Issues tracking 72 | 73 | * Feel free to submit issues with or request new features via [GitHub Issues](https://github.com/FireNero/AsyncIO/issues). 74 | * Before asking questions about library usage, please verify that it isn't covered in [Usage section](#usage). 75 | 76 | ### Pull requests 77 | 78 | * Before creating new pull request, please create a ticket for it. 79 | 80 | ## Licence 81 | 82 | Library is distributing under the MIT license. You can see details [here](https://github.com/FireNero/AsyncIO/blob/master/LICENSE). 83 | 84 | ## Roadmap 85 | 86 | 1. Implement async analog of [`File.Replace`](https://msdn.microsoft.com/en-us/library/9d9h163f(v=vs.110).aspx) method. 87 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects": [ "src", "test" ], 3 | "sdk": { 4 | "version": "1.0.0-preview2-1-003177" 5 | } 6 | } --------------------------------------------------------------------------------