Merge pull request #823 from DavidKarlas/master
[mono.git] / mcs / class / corlib / Test / System.IO / FileStreamTest.cs
1 // FileStreamTests.cs - NUnit2 Test Cases for System.IO.FileStream class
2 //
3 // Authors:
4 //      Ville Palo (vi64pa@koti.soon.fi)
5 //      Gert Driesen (gert.driesen@ardatis.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // 
8 // (C) Ville Palo
9 // (c) 2003 Ximian, Inc. (http://www.ximian.com)
10 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
11 // 
12
13 using NUnit.Framework;
14 using System;
15 using System.IO;
16 using System.Runtime.InteropServices;
17 using System.Text;
18 using System.Threading;
19
20 namespace MonoTests.System.IO
21 {
22         [TestFixture]
23         public class FileStreamTest
24         {
25                 string TempFolder = Path.Combine (Path.GetTempPath (), "MonoTests.System.IO.Tests");
26                 static readonly char DSC = Path.DirectorySeparatorChar;
27                 static bool MacOSX = false;
28
29                 [DllImport ("libc")]
30                 static extern int uname (IntPtr buf);
31
32                 [TearDown]
33                 public void TearDown ()
34                 {
35                         if (Directory.Exists (TempFolder))
36                                 Directory.Delete (TempFolder, true);
37                 }
38
39                 [SetUp]
40                 public void SetUp ()
41                 {
42                         if (Directory.Exists (TempFolder))
43                                 Directory.Delete (TempFolder, true);
44
45                         Directory.CreateDirectory (TempFolder);
46 #if !MOBILE                     
47                         // from XplatUI.cs
48                         IntPtr buf = Marshal.AllocHGlobal (8192);
49                         if (uname (buf) == 0)
50                                 MacOSX = Marshal.PtrToStringAnsi (buf) == "Darwin";
51                         Marshal.FreeHGlobal (buf);
52 #endif
53                 }
54
55                 public void TestCtr ()
56                 {
57                         string path = TempFolder + DSC + "testfilestream.tmp.1";
58                         DeleteFile (path);
59                         FileStream stream = null;
60                         try {
61                                 stream = new FileStream (path, FileMode.Create);
62                         } finally {
63
64                                 if (stream != null)
65                                         stream.Close ();
66                                 DeleteFile (path);
67                         }
68                 }
69
70                 [Test]
71                 [ExpectedException (typeof (ArgumentException))]
72                 public void CtorArgumentException1 ()
73                 {
74                         FileStream stream;
75                         stream = new FileStream ("", FileMode.Create);
76                         stream.Close ();
77                 }
78
79                 [Test]
80                 [ExpectedException (typeof (ArgumentNullException))]
81                 public void CtorArgumentNullException ()
82                 {
83                         FileStream stream = new FileStream (null, FileMode.Create);
84                         stream.Close ();
85                 }
86
87                 [Test]
88                 public void CtorFileNotFoundException_Mode_Open ()
89                 {
90                         // absolute path
91                         string path = TempFolder + DSC + "thisfileshouldnotexists.test";
92                         DeleteFile (path);
93                         FileStream stream = null;
94                         try {
95                                 stream = new FileStream (TempFolder + DSC + "thisfileshouldnotexists.test", FileMode.Open);
96                                 Assert.Fail ("#A1");
97                         } catch (FileNotFoundException ex) {
98                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#A2");
99                                 Assert.AreEqual (path, ex.FileName, "#A3");
100                                 Assert.IsNull (ex.InnerException, "#A4");
101                                 Assert.IsNotNull (ex.Message, "#A5");
102                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A6");
103                         } finally {
104                                 if (stream != null) {
105                                         stream.Close ();
106                                         stream = null;
107                                 }
108                                 DeleteFile (path);
109                         }
110
111                         // relative path
112                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
113                         Directory.SetCurrentDirectory (TempFolder);
114                         try {
115                                 stream = new FileStream ("thisfileshouldnotexists.test", FileMode.Open);
116                                 Assert.Fail ("#B1");
117                         } catch (FileNotFoundException ex) {
118                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
119                                 // under OSX 'var' is a symlink to 'private/var'
120                                 if (MacOSX)
121                                         path = "/private" + path;
122                                 Assert.AreEqual (path, ex.FileName, "#B3");
123                                 Assert.IsNull (ex.InnerException, "#B4");
124                                 Assert.IsNotNull (ex.Message, "#B5");
125                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B6");
126                         } finally {
127                                 // restore original current directory
128                                 Directory.SetCurrentDirectory (orignalCurrentDir);
129                                 if (stream != null)
130                                         stream.Close ();
131                                 DeleteFile (path);
132                         }
133                 }
134
135                 [Test]
136                 public void CtorFileNotFoundException_Mode_Truncate ()
137                 {
138                         // absolute path
139                         string path = TempFolder + DSC + "thisfileshouldNOTexists.test";
140                         DeleteFile (path);
141                         FileStream stream = null;
142                         try {
143                                 stream = new FileStream (path, FileMode.Truncate);
144                                 Assert.Fail ("#A1");
145                         } catch (FileNotFoundException ex) {
146                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#A2");
147                                 Assert.AreEqual (path, ex.FileName, "#A3");
148                                 Assert.IsNull (ex.InnerException, "#A4");
149                                 Assert.IsNotNull (ex.Message, "#A5");
150                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A6");
151                         } finally {
152                                 if (stream != null) {
153                                         stream.Close ();
154                                         stream = null;
155                                 }
156                                 DeleteFile (path);
157                         }
158
159                         // relative path
160                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
161                         Directory.SetCurrentDirectory (TempFolder);
162                         try {
163                                 stream = new FileStream ("thisfileshouldNOTexists.test", FileMode.Truncate);
164                                 Assert.Fail ("#B1");
165                         } catch (FileNotFoundException ex) {
166                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#B2");
167                                 // under OSX 'var' is a symlink to 'private/var'
168                                 if (MacOSX)
169                                         path = "/private" + path;
170                                 Assert.AreEqual (path, ex.FileName, "#B3");
171                                 Assert.IsNull (ex.InnerException, "#B4");
172                                 Assert.IsNotNull (ex.Message, "#B5");
173                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B6");
174                         } finally {
175                                 // restore original current directory
176                                 Directory.SetCurrentDirectory (orignalCurrentDir);
177                                 if (stream != null)
178                                         stream.Close ();
179                                 DeleteFile (path);
180                         }
181                 }
182
183                 [Test]
184                 public void CtorIOException1 ()
185                 {
186                         // absolute path
187                         string path = TempFolder + DSC + "thisfileshouldexists.test";
188                         FileStream stream = null;
189                         DeleteFile (path);
190                         try {
191                                 stream = new FileStream (path, FileMode.CreateNew);
192                                 stream.Close ();
193                                 stream = null;
194                                 stream = new FileStream (path, FileMode.CreateNew);
195                                 Assert.Fail ("#A1");
196                         } catch (IOException ex) {
197                                 Assert.AreEqual (typeof (IOException), ex.GetType (), "#A2");
198                                 Assert.IsNull (ex.InnerException, "#A3");
199                                 Assert.IsNotNull (ex.Message, "#A4");
200                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#A5");
201                         } finally {
202                                 if (stream != null) {
203                                         stream.Close ();
204                                         stream = null;
205                                 }
206                                 DeleteFile (path);
207                         }
208
209                         // relative path
210                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
211                         Directory.SetCurrentDirectory (TempFolder);
212                         try {
213                                 stream = new FileStream ("thisfileshouldexists.test", FileMode.CreateNew);
214                                 stream.Close ();
215                                 stream = null;
216                                 stream = new FileStream ("thisfileshouldexists.test", FileMode.CreateNew);
217                                 Assert.Fail ("#B1");
218                         } catch (IOException ex) {
219                                 Assert.AreEqual (typeof (IOException), ex.GetType (), "#B2");
220                                 Assert.IsNull (ex.InnerException, "#B3");
221                                 Assert.IsNotNull (ex.Message, "#B4");
222                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#B5");
223                         } finally {
224                                 // restore original current directory
225                                 Directory.SetCurrentDirectory (orignalCurrentDir);
226                                 if (stream != null)
227                                         stream.Close ();
228                                 DeleteFile (path);
229                         }
230                 }
231
232                 [Test]
233                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
234                 public void CtorArgumentOutOfRangeException1 ()
235                 {
236                         FileStream stream = null;
237                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
238                         DeleteFile (path);
239                         try {
240                                 stream = new FileStream (path, FileMode.Append | FileMode.CreateNew);
241                         } finally {
242                                 if (stream != null)
243                                         stream.Close ();
244                                 DeleteFile (path);
245                         }
246                 }
247
248                 [Test]
249                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
250                 public void CtorArgumentOutOfRangeException2 ()
251                 {
252                         FileStream stream = null;
253                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
254                         DeleteFile (path);
255                         try {
256                                 stream = new FileStream ("test.test.test", FileMode.Append | FileMode.Open);
257                         } finally {
258                                 if (stream != null)
259                                         stream.Close ();
260                                 DeleteFile (path);
261                         }
262                 }
263
264                 private void CtorDirectoryNotFoundException (FileMode mode)
265                 {
266                         string path = TempFolder + DSC + "thisDirectoryShouldNotExists";
267                         if (Directory.Exists (path))
268                                 Directory.Delete (path, true);
269
270                         FileStream stream = null;
271                         try {
272                                 stream = new FileStream (path + DSC + "eitherthisfile.test", mode);
273                         } finally {
274
275                                 if (stream != null)
276                                         stream.Close ();
277
278                                 if (Directory.Exists (path))
279                                         Directory.Delete (path, true);
280                         }
281                 }
282
283                 [Test]
284                 [ExpectedException (typeof (DirectoryNotFoundException))]
285                 public void CtorDirectoryNotFoundException_CreateNew ()
286                 {
287                         CtorDirectoryNotFoundException (FileMode.CreateNew);
288                 }
289
290                 [Test]
291                 [ExpectedException (typeof (DirectoryNotFoundException))]
292                 public void CtorDirectoryNotFoundException_Create ()
293                 {
294                         CtorDirectoryNotFoundException (FileMode.Create);
295                 }
296
297                 [Test]
298                 [ExpectedException (typeof (DirectoryNotFoundException))]
299                 public void CtorDirectoryNotFoundException_Open ()
300                 {
301                         CtorDirectoryNotFoundException (FileMode.Open);
302                 }
303
304                 [Test]
305                 [ExpectedException (typeof (DirectoryNotFoundException))]
306                 public void CtorDirectoryNotFoundException_OpenOrCreate ()
307                 {
308                         CtorDirectoryNotFoundException (FileMode.OpenOrCreate);
309                 }
310
311                 [Test]
312                 [ExpectedException (typeof (DirectoryNotFoundException))]
313                 public void CtorDirectoryNotFoundException_Truncate ()
314                 {
315                         CtorDirectoryNotFoundException (FileMode.Truncate);
316                 }
317
318                 [Test]
319                 [ExpectedException (typeof (DirectoryNotFoundException))]
320                 public void CtorDirectoryNotFoundException_Append ()
321                 {
322                         CtorDirectoryNotFoundException (FileMode.Append);
323                 }
324
325                 [Test]
326                 public void CtorDirectoryNotFound_RelativePath ()
327                 {
328                         string orignalCurrentDir = Directory.GetCurrentDirectory ();
329                         Directory.SetCurrentDirectory (TempFolder);
330                         string relativePath = "DirectoryDoesNotExist" + Path.DirectorySeparatorChar + "file.txt";
331                         string fullPath = Path.Combine (TempFolder, relativePath);
332                         try {
333                                 new FileStream (relativePath, FileMode.Open);
334                                 Assert.Fail ("#A1");
335                         } catch (DirectoryNotFoundException ex) {
336                                 Assert.AreEqual (typeof (DirectoryNotFoundException), ex.GetType (), "#A2");
337                                 Assert.IsNull (ex.InnerException, "#A3");
338                                 Assert.IsNotNull (ex.Message, "#A4");
339                                 Assert.IsTrue (ex.Message.IndexOf (fullPath) != -1, "#A5");
340                         } finally {
341                                 // restore original current directory
342                                 Directory.SetCurrentDirectory (orignalCurrentDir);
343                         }
344                 }
345
346                 [Test]
347                 // FileShare.Inheritable is ignored, but file does not exist
348                 [ExpectedException (typeof (FileNotFoundException))]
349                 public void CtorArgumentOutOfRangeException3 ()
350                 {
351                         string path = TempFolder + DSC + "CtorArgumentOutOfRangeException1";
352                         DeleteFile (path);
353
354                         FileStream stream = null;
355                         try {
356                                 stream = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.Inheritable);
357                         } finally {
358                                 if (stream != null)
359                                         stream.Close ();
360                                 DeleteFile (path);
361                         }
362                 }
363
364                 [Test]
365                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
366                 public void CtorArgumentOutOfRangeException4 ()
367                 {
368                         string path = TempFolder + DSC + "CtorArgumentOutOfRangeException4";
369                         DeleteFile (path);
370
371                         FileStream stream = null;
372                         try {
373                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read, FileShare.ReadWrite, -1);
374                         } finally {
375                                 if (stream != null)
376                                         stream.Close ();
377                                 DeleteFile (path);
378                         }
379                 }
380
381                 [Test]
382                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
383                 public void CtorBufferSizeZero ()
384                 {
385                         // Buffer size can't be zero
386
387                         string path = Path.Combine (TempFolder, "CtorBufferSizeZero");
388                         DeleteFile (path);
389
390                         FileStream stream = null;
391                         try {
392                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.Write, FileShare.ReadWrite, 0);
393                         } finally {
394                                 if (stream != null)
395                                         stream.Close ();
396                                 DeleteFile (path);
397                         }
398                 }
399
400                 [Test]
401                 [ExpectedException (typeof (ArgumentException))]
402                 public void CtorArgumentException2 ()
403                 {
404                         // FileMode.CreateNew && FileAccess.Read
405
406                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
407                         FileStream stream = null;
408
409                         DeleteFile (path);
410
411                         try {
412                                 stream = new FileStream (".test.test.test.2", FileMode.CreateNew, FileAccess.Read, FileShare.None | FileShare.Write);
413                         } finally {
414
415                                 if (stream != null)
416                                         stream.Close ();
417                                 DeleteFile (path);
418                         }
419                 }
420
421
422                 [Test]
423                 // FileShare.Inheritable is ignored, but file does not exist
424                 [ExpectedException (typeof (FileNotFoundException))]
425                 public void CtorArgumentOutOfRangeException5 ()
426                 {
427                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
428                         DeleteFile (path);
429
430                         FileStream stream = null;
431                         try {
432                                 stream = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.Inheritable | FileShare.ReadWrite);
433                         } finally {
434                                 if (stream != null)
435                                         stream.Close ();
436                                 DeleteFile (path);
437                         }
438                 }
439
440
441                 [Test]
442                 [ExpectedException (typeof (ArgumentException))]
443                 public void CtorArgumentException3 ()
444                 {
445                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
446                         FileStream stream = null;
447
448                         DeleteFile (path);
449
450                         try {
451                                 stream = new FileStream (".test.test.test.2", FileMode.Truncate, FileAccess.Read);
452                         } finally {
453                                 if (stream != null)
454                                         stream.Close ();
455
456                                 DeleteFile (path);
457                         }
458                 }
459
460                 [Test]
461                 public void ModeAndAccessCombinations ()
462                 {
463                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
464                         DeleteFile (path);
465                         FileStream stream = null;
466
467                         // Append / Read
468                         try {
469                                 // Append access can be requested only in write-only mode
470                                 stream = new FileStream (path, FileMode.Append, FileAccess.Read);
471                                 Assert.Fail ("#A1");
472                         } catch (ArgumentException ex) {
473                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
474                         } finally {
475                                 if (stream != null)
476                                         stream.Close ();
477
478                                 DeleteFile (path);
479                         }
480
481                         // Append / ReadWrite
482                         try {
483                                 // Append access can be requested only in write-only mode
484                                 stream = new FileStream (path, FileMode.Append, FileAccess.ReadWrite);
485                                 Assert.Fail ("#B1");
486                         } catch (ArgumentException ex) {
487                                 // make sure it is exact this exception, and not a derived type
488                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#B2");
489                         } finally {
490                                 if (stream != null)
491                                         stream.Close ();
492
493                                 DeleteFile (path);
494                         }
495
496                         // Append / Write
497                         try {
498                                 stream = new FileStream (path, FileMode.Append, FileAccess.Write);
499                         } finally {
500                                 if (stream != null)
501                                         stream.Close ();
502
503                                 DeleteFile (path);
504                         }
505
506                         // Create / Read
507                         try {
508                                 stream = new FileStream (path, FileMode.Create, FileAccess.Read);
509                                 Assert.Fail ("#C1");
510                         } catch (ArgumentException ex) {
511                                 // make sure it is exact this exception, and not a derived type
512                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#C2");
513                         } finally {
514                                 if (stream != null)
515                                         stream.Close ();
516
517                                 DeleteFile (path);
518                         }
519
520                         // Create / ReadWrite
521                         try {
522                                 stream = new FileStream (path, FileMode.Create, FileAccess.ReadWrite);
523                         } finally {
524                                 if (stream != null)
525                                         stream.Close ();
526
527                                 DeleteFile (path);
528                         }
529
530                         // Create / Write
531                         try {
532                                 stream = new FileStream (path, FileMode.Create, FileAccess.Write);
533                         } finally {
534                                 if (stream != null)
535                                         stream.Close ();
536
537                                 DeleteFile (path);
538                         }
539
540                         // CreateNew / Read
541                         try {
542                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.Read);
543                                 Assert.Fail ("#D1");
544                         } catch (ArgumentException ex) {
545                                 // make sure it is exact this exception, and not a derived type
546                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#D2");
547                         } finally {
548                                 if (stream != null)
549                                         stream.Close ();
550
551                                 DeleteFile (path);
552                         }
553
554                         // CreateNew / ReadWrite
555                         try {
556                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
557                         } finally {
558                                 if (stream != null)
559                                         stream.Close ();
560
561                                 DeleteFile (path);
562                         }
563
564                         // CreateNew / Write
565                         try {
566                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.Write);
567                         } finally {
568                                 if (stream != null)
569                                         stream.Close ();
570
571                                 DeleteFile (path);
572                         }
573
574                         // Open / Read
575                         try {
576                                 stream = new FileStream (path, FileMode.Open, FileAccess.Read);
577                                 Assert.Fail ("#E1");
578                         } catch (FileNotFoundException ex) {
579                                 // make sure it is exact this exception, and not a derived type
580                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#E2");
581                                 Assert.AreEqual (path, ex.FileName, "#E3");
582                                 Assert.IsNull (ex.InnerException, "#E4");
583                                 Assert.IsNotNull (ex.Message, "#E5");
584                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#E6");
585                         } finally {
586                                 if (stream != null)
587                                         stream.Close ();
588
589                                 DeleteFile (path);
590                         }
591
592                         // Open / ReadWrite
593                         try {
594                                 stream = new FileStream (path, FileMode.Open, FileAccess.ReadWrite);
595                                 Assert.Fail ("#F1");
596                         } catch (FileNotFoundException ex) {
597                                 // make sure it is exact this exception, and not a derived type
598                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#F2");
599                                 Assert.AreEqual (path, ex.FileName, "#F3");
600                                 Assert.IsNull (ex.InnerException, "#F4");
601                                 Assert.IsNotNull (ex.Message, "#F5");
602                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#F6");
603                         } finally {
604                                 if (stream != null)
605                                         stream.Close ();
606
607                                 DeleteFile (path);
608                         }
609
610                         // Open / Write
611                         try {
612                                 stream = new FileStream (path, FileMode.Open, FileAccess.Write);
613                                 Assert.Fail ("#G1");
614                         } catch (FileNotFoundException ex) {
615                                 // make sure it is exact this exception, and not a derived type
616                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#G2");
617                                 Assert.AreEqual (path, ex.FileName, "#G3");
618                                 Assert.IsNull (ex.InnerException, "#G4");
619                                 Assert.IsNotNull (ex.Message, "#G5");
620                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#G6");
621                         } finally {
622                                 if (stream != null)
623                                         stream.Close ();
624
625                                 DeleteFile (path);
626                         }
627
628                         // OpenOrCreate / Read
629                         try {
630                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
631                         } finally {
632                                 if (stream != null)
633                                         stream.Close ();
634
635                                 DeleteFile (path);
636                         }
637
638                         // OpenOrCreate / ReadWrite
639                         try {
640                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
641                         } finally {
642                                 if (stream != null)
643                                         stream.Close ();
644
645                                 DeleteFile (path);
646                         }
647
648                         // OpenOrCreate / Write
649                         try {
650                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
651                         } finally {
652                                 if (stream != null)
653                                         stream.Close ();
654
655                                 DeleteFile (path);
656                         }
657
658                         // Truncate / Read
659                         try {
660                                 stream = new FileStream (path, FileMode.Truncate, FileAccess.Read);
661                                 Assert.Fail ("#H1");
662                         } catch (ArgumentException ex) {
663                                 // make sure it is exact this exception, and not a derived type
664                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#H2");
665                         } finally {
666                                 if (stream != null)
667                                         stream.Close ();
668
669                                 DeleteFile (path);
670                         }
671
672                         // Truncate / ReadWrite
673                         try {
674                                 stream = new FileStream (path, FileMode.Truncate, FileAccess.ReadWrite);
675                                 Assert.Fail ("#I1");
676                         } catch (FileNotFoundException ex) {
677                                 // make sure it is exact this exception, and not a derived type
678                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#I2");
679                                 Assert.AreEqual (path, ex.FileName, "#I3");
680                                 Assert.IsNull (ex.InnerException, "#I4");
681                                 Assert.IsNotNull (ex.Message, "#I5");
682                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#I6");
683                         } finally {
684                                 if (stream != null)
685                                         stream.Close ();
686
687                                 DeleteFile (path);
688                         }
689
690                         // Truncate / Write
691                         try {
692                                 stream = new FileStream (path, FileMode.Truncate, FileAccess.Write);
693                                 Assert.Fail ("#J1");
694                         } catch (FileNotFoundException ex) {
695                                 // make sure it is exact this exception, and not a derived type
696                                 Assert.AreEqual (typeof (FileNotFoundException), ex.GetType (), "#J2");
697                                 Assert.AreEqual (path, ex.FileName, "#J3");
698                                 Assert.IsNull (ex.InnerException, "#J4");
699                                 Assert.IsNotNull (ex.Message, "#J5");
700                                 Assert.IsTrue (ex.Message.IndexOf (path) != -1, "#J6");
701                         } finally {
702                                 if (stream != null)
703                                         stream.Close ();
704
705                                 DeleteFile (path);
706                         }
707                 }
708
709 #if !TARGET_JVM // No support IntPtr file handles under TARGET_JVM
710                 [Test, ExpectedException (typeof (IOException))]
711                 public void CtorIOException2 ()
712                 {
713                         FileStream stream = null;
714                         try {
715                                 stream = new FileStream (new IntPtr (Int32.MaxValue), FileAccess.Read);
716                         } finally {
717                                 if (stream != null)
718                                         stream.Close ();
719                         }
720                 }
721 #endif // TARGET_JVM
722
723                 [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
724                 [Test, ExpectedException (typeof (IOException))]
725                 public void CtorIOException ()
726                 {
727                         string path = TempFolder + DSC + "CTorIOException.Test";
728                         FileStream stream = null;
729                         FileStream stream2 = null;
730                         DeleteFile (path);
731
732                         try {
733                                 stream = new FileStream (path, FileMode.CreateNew);
734
735                                 // used by an another process
736                                 stream2 = new FileStream (path, FileMode.OpenOrCreate);
737                         } finally {
738                                 if (stream != null)
739                                         stream.Close ();
740                                 if (stream2 != null)
741                                         stream2.Close ();
742                                 DeleteFile (path);
743                         }
744                 }
745
746                 [Test]
747                 public void CtorAccess1Read2Read ()
748                 {
749                         FileStream fs = null;
750                         FileStream fs2 = null;
751                         string fn = Path.Combine (TempFolder, "temp");
752                         try {
753                                 if (!File.Exists (fn)) {
754                                         TextWriter tw = File.CreateText (fn);
755                                         tw.Write ("FOO");
756                                         tw.Close ();
757                                 }
758                                 fs = new FileStream (fn, FileMode.Open, FileAccess.Read);
759                                 fs2 = new FileStream (fn, FileMode.Open, FileAccess.Read);
760                         } finally {
761                                 if (fs != null)
762                                         fs.Close ();
763                                 if (fs2 != null)
764                                         fs2.Close ();
765                                 if (File.Exists (fn))
766                                         File.Delete (fn);
767                         }
768                 }
769
770                 [Test]
771                 [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
772                 [ExpectedException (typeof (IOException))]
773                 public void CtorAccess1Read2Write ()
774                 {
775                         string fn = Path.Combine (TempFolder, "temp");
776                         FileStream fs1 = null;
777                         FileStream fs2 = null;
778                         try {
779                                 if (!File.Exists (fn)) {
780                                         using (TextWriter tw = File.CreateText (fn)) {
781                                                 tw.Write ("FOO");
782                                         }
783                                 }
784                                 fs1 = new FileStream (fn, FileMode.Open, FileAccess.Read);
785                                 fs2 = new FileStream (fn, FileMode.Create, FileAccess.Write);
786                         } finally {
787                                 if (fs1 != null)
788                                         fs1.Close ();
789                                 if (fs2 != null)
790                                         fs2.Close ();
791                                 if (File.Exists (fn))
792                                         File.Delete (fn);
793                         }
794                 }
795
796                 [Test]
797                 [Category("TargetJvmNotSupported")] // File sharing not supported for TARGET_JVM
798                 [ExpectedException (typeof (IOException))]
799                 public void CtorAccess1Write2Write ()
800                 {
801                         string fn = Path.Combine (TempFolder, "temp");
802                         FileStream fs1 = null;
803                         FileStream fs2 = null;
804                         try {
805                                 if (File.Exists (fn))
806                                         File.Delete (fn);
807                                 fs1 = new FileStream (fn, FileMode.Create, FileAccess.Write);
808                                 fs2 = new FileStream (fn, FileMode.Create, FileAccess.Write);
809                         } finally {
810                                 if (fs1 != null)
811                                         fs1.Close ();
812                                 if (fs2 != null)
813                                         fs2.Close ();
814                                 if (File.Exists (fn))
815                                         File.Delete (fn);
816                         }
817                 }
818
819                 [Test]
820                 [ExpectedException (typeof (UnauthorizedAccessException))]
821                 public void CtorReadDirectoryAsFile ()
822                 {
823                         FileStream stream = null;
824                         try {
825                                 stream = new FileStream (TempFolder, FileMode.Open, FileAccess.Read);
826                         } finally {
827                                 if (stream != null)
828                                         stream.Close ();
829                         }
830                 }
831
832                 [Test] // bug #79250
833                 public void FileShare_Delete ()
834                 {
835                         string fn = Path.Combine (TempFolder, "temp");
836                         
837                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Delete)) {
838                                 s.Write (new byte [1] { 0x5 }, 0, 1);
839                                 File.Delete (fn);
840                         }
841
842                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete)) {
843                                 s.Write (new byte [1] { 0x5 }, 0, 1);
844                                 File.Delete (fn);
845                         }
846
847                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write | FileShare.Delete)) {
848                                 s.Write (new byte [1] { 0x5 }, 0, 1);
849                                 File.Delete (fn);
850                         }
851
852                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read | FileShare.Delete)) {
853                                 s.Write (new byte [1] { 0x5 }, 0, 1);
854                                 File.Delete (fn);
855                         }
856
857                         using (Stream s = new FileStream (fn, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Inheritable | FileShare.Delete)) {
858                                 s.Write (new byte [1] { 0x5 }, 0, 1);
859                                 File.Delete (fn);
860                         }
861                 }
862
863                 [Test]
864                 public void Write ()
865                 {
866                         string path = TempFolder + DSC + "FileStreamTest.Write";
867
868                         DeleteFile (path);
869
870                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite, 8);
871
872                         byte[] outbytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
873                         byte[] bytes = new byte[15];
874
875                         // Check that the data is flushed when we overflow the buffer
876                         // with a large amount of data
877                         stream.Write (outbytes, 0, 5);
878                         stream.Write (outbytes, 5, 10);
879                         stream.Seek (0, SeekOrigin.Begin);
880
881                         stream.Read (bytes, 0, 15);
882                         for (int i = 0; i < 15; ++i)
883                                 Assert.AreEqual (i + 1, bytes[i], "#1");
884
885                         // Check that the data is flushed when we overflow the buffer
886                         // with a small amount of data
887                         stream.Write (outbytes, 0, 7);
888                         stream.Write (outbytes, 7, 7);
889                         stream.Write (outbytes, 14, 1);
890
891                         stream.Read (bytes, 0, 15);
892                         stream.Seek (15, SeekOrigin.Begin);
893                         for (int i = 0; i < 15; ++i)
894                                 Assert.AreEqual (i + 1, bytes[i], "#2");
895                         stream.Close ();
896                 }
897
898                 [Test]
899                 public void Length ()
900                 {
901                         // Test that the Length property takes into account the data
902                         // in the buffer
903                         string path = TempFolder + DSC + "FileStreamTest.Length";
904
905                         DeleteFile (path);
906
907                         FileStream stream = new FileStream (path, FileMode.CreateNew);
908
909                         byte[] outbytes = new byte[] { 1, 2, 3, 4 };
910
911                         stream.Write (outbytes, 0, 4);
912                         Assert.AreEqual (4, stream.Length);
913                         stream.Close ();
914                 }
915
916                 [Test]
917                 public void Flush ()
918                 {
919                         string path = TempFolder + DSC + "FileStreamTest.Flush";
920                         FileStream stream = null;
921                         FileStream stream2 = null;
922
923                         DeleteFile (path);
924
925                         try {
926                                 stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
927                                 stream2 = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
928
929                                 stream.Write (new byte[] { 1, 2, 3, 4, 5 }, 0, 5);
930
931                                 byte[] bytes = new byte[5];
932                                 stream2.Read (bytes, 0, 5);
933                                 Assert.AreEqual (0, bytes[0], "#A1");
934                                 Assert.AreEqual (0, bytes[1], "#A2");
935                                 Assert.AreEqual (0, bytes[2], "#A3");
936                                 Assert.AreEqual (0, bytes[3], "#A4");
937
938                                 stream.Flush ();
939                                 stream2.Read (bytes, 0, 5);
940                                 Assert.AreEqual (1, bytes[0], "#B1");
941                                 Assert.AreEqual (2, bytes[1], "#B2");
942                                 Assert.AreEqual (3, bytes[2], "#B3");
943                                 Assert.AreEqual (4, bytes[3], "#B4");
944                         } finally {
945                                 if (stream != null)
946                                         stream.Close ();
947                                 if (stream2 != null)
948                                         stream2.Close ();
949
950                                 DeleteFile (path);
951                         }
952                 }
953
954                 public void TestDefaultProperties ()
955                 {
956                         string path = TempFolder + Path.DirectorySeparatorChar + "testfilestream.tmp.2";
957                         DeleteFile (path);
958
959                         FileStream stream = new FileStream (path, FileMode.Create);
960
961                         Assert.IsTrue (stream.CanRead, "#A1");
962                         Assert.IsTrue (stream.CanSeek, "#A2");
963                         Assert.IsTrue (stream.CanWrite, "#A3");
964                         Assert.IsFalse (stream.IsAsync, "#A4");
965                         Assert.IsTrue (stream.Name.EndsWith (path), "#A5");
966                         Assert.AreEqual (0, stream.Position, "#A6");
967                         Assert.AreEqual ("System.IO.FileStream", stream.ToString (), "#A7");
968                         stream.Close ();
969                         DeleteFile (path);
970
971                         stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
972                         Assert.IsTrue (stream.CanRead, "#B1");
973                         Assert.IsTrue (stream.CanSeek, "#B2");
974                         Assert.IsFalse (stream.CanWrite, "#B3");
975                         Assert.IsFalse (stream.IsAsync, "#B4");
976                         Assert.IsTrue (stream.Name.EndsWith (path), "#B5");
977                         Assert.AreEqual (0, stream.Position, "#B6");
978                         Assert.AreEqual ("System.IO.FileStream", stream.ToString (), "#B7");
979                         stream.Close ();
980
981                         stream = new FileStream (path, FileMode.Truncate, FileAccess.Write, FileShare.ReadWrite);
982                         Assert.IsFalse (stream.CanRead, "#C1");
983                         Assert.IsTrue (stream.CanSeek, "#C2");
984                         Assert.IsTrue (stream.CanWrite, "#C3");
985                         Assert.IsFalse (stream.IsAsync, "#C4");
986                         Assert.IsTrue (stream.Name.EndsWith ("testfilestream.tmp.2"), "#C5");
987                         Assert.AreEqual (0, stream.Position, "#C6");
988                         Assert.AreEqual ("System.IO.FileStream", stream.ToString (), "#C7");
989                         stream.Close ();
990                         DeleteFile (path);
991                 }
992
993                 [Category ("NotWorking")]
994                 // Bug: 71371 -> duplicate and WONTFIX.
995                 public void TestLock_FailsOnMono ()
996                 {
997                         string path = TempFolder + Path.DirectorySeparatorChar + "TestLock";
998                         DeleteFile (path);
999
1000                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
1001
1002                         stream.Write (new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10);
1003                         stream.Close ();
1004
1005                         stream = new FileStream (path, FileMode.Open, FileAccess.ReadWrite);
1006
1007                         stream.Lock (0, 5);
1008
1009                         FileStream stream2 = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
1010
1011                         byte[] bytes = new byte[5];
1012                         try {
1013                                 stream2.Read (bytes, 0, 5);
1014                                 Assert.Fail ("#1");
1015                         } catch (Exception e) {
1016                                 Assert.AreEqual (typeof (IOException), e.GetType (), "#2");
1017                         }
1018
1019                         stream.Close ();
1020                         stream2.Close ();
1021
1022                         DeleteFile (path);
1023                 }
1024
1025                 [Category("TargetJvmNotSupported")] // File locking not supported for TARGET_JVM
1026                 public void TestLock ()
1027                 {
1028                         string path = TempFolder + Path.DirectorySeparatorChar + "TestLock";
1029                         DeleteFile (path);
1030
1031                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
1032
1033                         stream.Write (new Byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10);
1034                         stream.Close ();
1035
1036                         stream = new FileStream (path, FileMode.Open, FileAccess.ReadWrite);
1037
1038                         stream.Lock (0, 5);
1039
1040                         FileStream stream2 = new FileStream (path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
1041
1042                         byte[] bytes = new byte[5];
1043                         try {
1044                                 stream2.Read (bytes, 0, 5);
1045                                 Assert.Fail ("#A1");
1046                         } catch (Exception) {
1047                                 // Bug #71371: on MS.NET you get an IOException detailing a lock
1048                                 // Assert.AreEqual (typeof (IOException), e.GetType (), "#A2");
1049                         }
1050
1051                         stream2.Seek (5, SeekOrigin.Begin);
1052                         stream2.Read (bytes, 0, 5);
1053
1054                         Assert.AreEqual (5, bytes[0], "#B1");
1055                         Assert.AreEqual (6, bytes[1], "#B2");
1056                         Assert.AreEqual (7, bytes[2], "#B3");
1057                         Assert.AreEqual (8, bytes[3], "#B4");
1058                         Assert.AreEqual (9, bytes[4], "#B5");
1059
1060                         stream.Unlock (0, 5);
1061                         stream2.Seek (0, SeekOrigin.Begin);
1062                         stream2.Read (bytes, 0, 5);
1063
1064                         Assert.AreEqual (0, bytes[0], "#C1");
1065                         Assert.AreEqual (1, bytes[1], "#C2");
1066                         Assert.AreEqual (2, bytes[2], "#C3");
1067                         Assert.AreEqual (3, bytes[3], "#C4");
1068                         Assert.AreEqual (4, bytes[4], "#C5");
1069
1070                         stream.Close ();
1071                         stream2.Close ();
1072
1073                         DeleteFile (path);
1074                 }
1075
1076                 [Test]
1077                 public void Seek ()
1078                 {
1079                         string path = TempFolder + DSC + "FST.Seek.Test";
1080                         DeleteFile (path);
1081
1082                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
1083                         FileStream stream2 = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
1084
1085                         stream.Write (new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 10 }, 0, 9);
1086                         Assert.AreEqual (5, stream2.Seek (5, SeekOrigin.Begin), "#1");
1087                         Assert.AreEqual (-1, stream2.ReadByte (), "#2");
1088
1089                         Assert.AreEqual (2, stream2.Seek (-3, SeekOrigin.Current), "#3");
1090                         Assert.AreEqual (-1, stream2.ReadByte (), "#4");
1091
1092                         Assert.AreEqual (12, stream.Seek (3, SeekOrigin.Current), "#5");
1093                         Assert.AreEqual (-1, stream.ReadByte (), "#6");
1094
1095                         Assert.AreEqual (5, stream.Seek (-7, SeekOrigin.Current), "#7");
1096                         Assert.AreEqual (6, stream.ReadByte (), "#8");
1097
1098                         Assert.AreEqual (5, stream2.Seek (5, SeekOrigin.Begin), "#9");
1099                         Assert.AreEqual (6, stream2.ReadByte (), "#10");
1100
1101                         stream.Close ();
1102                         stream2.Close ();
1103
1104                         DeleteFile (path);
1105                 }
1106
1107                 public void TestSeek ()
1108                 {
1109                         string path = TempFolder + Path.DirectorySeparatorChar + "TestSeek";
1110                         DeleteFile (path);
1111
1112                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite);
1113                         stream.Write (new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10);
1114
1115                         stream.Seek (5, SeekOrigin.End);
1116                         Assert.AreEqual (-1, stream.ReadByte (), "#1");
1117
1118                         stream.Seek (-5, SeekOrigin.End);
1119                         Assert.AreEqual (6, stream.ReadByte (), "#2");
1120
1121                         try {
1122                                 stream.Seek (-11, SeekOrigin.End);
1123                                 Assert.Fail ("#3");
1124                         } catch (Exception e) {
1125                                 Assert.AreEqual (typeof (IOException), e.GetType (), "#4");
1126                         }
1127
1128                         stream.Seek (19, SeekOrigin.Begin);
1129                         Assert.AreEqual (-1, stream.ReadByte (), "#5");
1130
1131                         stream.Seek (1, SeekOrigin.Begin);
1132                         Assert.AreEqual (2, stream.ReadByte (), "#6");
1133
1134                         stream.Seek (3, SeekOrigin.Current);
1135                         Assert.AreEqual (6, stream.ReadByte (), "#7");
1136
1137                         stream.Seek (-2, SeekOrigin.Current);
1138                         Assert.AreEqual (5, stream.ReadByte (), "#8");
1139
1140                         stream.Flush ();
1141
1142                         // Test that seeks work correctly when seeking inside the buffer
1143                         stream.Seek (0, SeekOrigin.Begin);
1144                         stream.WriteByte (0);
1145                         stream.WriteByte (1);
1146                         stream.Seek (0, SeekOrigin.Begin);
1147                         byte[] buf = new byte[1];
1148                         buf[0] = 2;
1149                         stream.Write (buf, 0, 1);
1150                         stream.Write (buf, 0, 1);
1151                         stream.Flush ();
1152                         stream.Seek (0, SeekOrigin.Begin);
1153                         Assert.AreEqual (2, stream.ReadByte (), "#9");
1154                         Assert.AreEqual (2, stream.ReadByte (), "#10");
1155
1156                         stream.Close ();
1157
1158                         DeleteFile (path);
1159                 }
1160
1161                 public void TestClose ()
1162                 {
1163                         string path = TempFolder + Path.DirectorySeparatorChar + "TestClose";
1164                         DeleteFile (path);
1165
1166                         FileStream stream = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite);
1167
1168                         stream.Write (new byte[] { 1, 2, 3, 4 }, 0, 4);
1169                         stream.ReadByte ();
1170                         stream.Close ();
1171
1172                         try {
1173                                 stream.ReadByte ();
1174                                 Assert.Fail ("#A1");
1175                         } catch (Exception e) {
1176                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#A2");
1177                         }
1178
1179                         try {
1180                                 stream.WriteByte (64);
1181                                 Assert.Fail ("#B1");
1182                         } catch (Exception e) {
1183                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#B2");
1184                         }
1185
1186                         try {
1187                                 stream.Flush ();
1188                                 Assert.Fail ("#C1");
1189                         } catch (Exception e) {
1190                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#C2");
1191                         }
1192
1193                         try {
1194                                 long l = stream.Length;
1195                                 Assert.Fail ("#D1");
1196                         } catch (Exception e) {
1197                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#D2");
1198                         }
1199
1200                         try {
1201                                 long l = stream.Position;
1202                                 Assert.Fail ("#E1");
1203                         } catch (Exception e) {
1204                                 Assert.AreEqual (typeof (ObjectDisposedException), e.GetType (), "#E2");
1205                         }
1206
1207                         Assert.IsFalse (stream.CanRead, "#F1");
1208                         Assert.IsFalse (stream.CanSeek, "#F2");
1209                         Assert.IsFalse (stream.CanWrite, "#F3");
1210                         Assert.IsTrue (stream.Name.EndsWith (path), "#F4");
1211
1212                         DeleteFile (path);
1213                 }
1214
1215
1216                 /// <summary>
1217                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1218                 /// when the stream is opened with access mode <see cref="FileAccess.Read" /> and the
1219                 /// <see cref="FileStream.Write(byte[], int, int)" /> method is called.
1220                 /// </summary>
1221                 [Test]
1222                 [ExpectedException (typeof (NotSupportedException))]
1223                 public void TestWriteVerifyAccessMode ()
1224                 {
1225                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1226                         DeleteFile (path);
1227
1228                         FileStream stream = null;
1229                         byte[] buffer;
1230
1231                         try {
1232                                 buffer = Encoding.ASCII.GetBytes ("test");
1233                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1234                                 stream.Write (buffer, 0, buffer.Length);
1235                         } finally {
1236                                 if (stream != null)
1237                                         stream.Close ();
1238                                 DeleteFile (path);
1239                         }
1240                 }
1241
1242                 /// <summary>
1243                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1244                 /// when the stream is opened with access mode <see cref="FileAccess.Read" /> and the
1245                 /// <see cref="FileStream.WriteByte(byte)" /> method is called.
1246                 /// </summary>
1247                 [Test]
1248                 [ExpectedException (typeof (NotSupportedException))]
1249                 public void TestWriteByteVerifyAccessMode ()
1250                 {
1251                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1252                         DeleteFile (path);
1253
1254                         FileStream stream = null;
1255
1256                         try {
1257                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1258                                 stream.WriteByte (Byte.MinValue);
1259                         } finally {
1260                                 if (stream != null)
1261                                         stream.Close ();
1262                                 DeleteFile (path);
1263                         }
1264                 }
1265
1266                 /// <summary>
1267                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1268                 /// when the stream is opened with access mode <see cref="FileAccess.Write" /> and the
1269                 /// <see cref="FileStream.Read(byte[], int, int)" /> method is called.
1270                 /// </summary>
1271                 [Test]
1272                 [ExpectedException (typeof (NotSupportedException))]
1273                 public void TestReadVerifyAccessMode ()
1274                 {
1275                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1276                         DeleteFile (path);
1277
1278                         FileStream stream = null;
1279                         byte[] buffer = new byte[100];
1280
1281                         try {
1282                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1283                                 stream.Read (buffer, 0, buffer.Length);
1284                         } finally {
1285                                 if (stream != null)
1286                                         stream.Close ();
1287                         }
1288                 }
1289
1290                 /// <summary>
1291                 /// Checks whether the <see cref="FileStream" /> throws a <see cref="NotSupportedException" />
1292                 /// when the stream is opened with access mode <see cref="FileAccess.Write" /> and the
1293                 /// <see cref="FileStream.ReadByte()" /> method is called.
1294                 /// </summary>
1295                 [Test]
1296                 [ExpectedException (typeof (NotSupportedException))]
1297                 public void TestReadByteVerifyAccessMode ()
1298                 {
1299                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1300                         DeleteFile (path);
1301
1302                         FileStream stream = null;
1303
1304                         try {
1305                                 stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1306                                 int readByte = stream.ReadByte ();
1307                         } finally {
1308                                 if (stream != null)
1309                                         stream.Close ();
1310                                 DeleteFile (path);
1311                         }
1312                 }
1313
1314 #if !TARGET_JVM // No support IntPtr file handles under TARGET_JVM
1315                 // Check that the stream is flushed even when it doesn't own the
1316                 // handle
1317                 [Test]
1318                 public void TestFlushNotOwningHandle ()
1319                 {
1320                         string path = Path.Combine (TempFolder, "TestFlushNotOwningHandle");
1321                         DeleteFile (path);
1322
1323                         FileStream s = new FileStream (path, FileMode.Create);
1324                         using (FileStream s2 = new FileStream (s.Handle, FileAccess.Write, false)) {
1325                                 byte[] buf = new byte[2];
1326                                 buf[0] = (int) '1';
1327                                 s2.Write (buf, 0, 1);
1328                         }
1329
1330                         s.Position = 0;
1331                         Assert.AreEqual ((int) '1', s.ReadByte ());
1332                         s.Close ();
1333                 }
1334 #endif // TARGET_JVM
1335
1336                 private void DeleteFile (string path)
1337                 {
1338                         if (File.Exists (path))
1339                                 File.Delete (path);
1340                 }
1341
1342                 [Test]
1343                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1344                 public void Read_OffsetNegative ()
1345                 {
1346                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1347                         DeleteFile (path);
1348
1349                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1350                                 stream.Read (new byte[0], -1, 1);
1351                         }
1352                 }
1353
1354                 [Test]
1355                 [ExpectedException (typeof (ArgumentException))]
1356                 public void Read_OffsetOverflow ()
1357                 {
1358                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1359                         DeleteFile (path);
1360
1361                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1362                                 stream.Read (new byte[0], Int32.MaxValue, 1);
1363                         }
1364                 }
1365
1366                 [Test]
1367                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1368                 public void Read_CountNegative ()
1369                 {
1370                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1371                         DeleteFile (path);
1372
1373                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1374                                 stream.Read (new byte[0], 1, -1);
1375                         }
1376                 }
1377
1378                 [Test]
1379                 [ExpectedException (typeof (ArgumentException))]
1380                 public void Read_CountOverflow ()
1381                 {
1382                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1383                         DeleteFile (path);
1384
1385                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1386                                 stream.Read (new byte[0], 1, Int32.MaxValue);
1387                         }
1388                 }
1389
1390                 [Test]
1391                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1392                 public void Write_OffsetNegative ()
1393                 {
1394                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1395                         DeleteFile (path);
1396
1397                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1398                                 stream.Write (new byte[0], -1, 1);
1399                         }
1400                 }
1401
1402                 [Test]
1403                 [ExpectedException (typeof (ArgumentException))]
1404                 public void Write_OffsetOverflow ()
1405                 {
1406                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1407                         DeleteFile (path);
1408
1409                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1410                                 stream.Write (new byte[0], Int32.MaxValue, 1);
1411                         }
1412                 }
1413
1414                 [Test]
1415                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1416                 public void Write_CountNegative ()
1417                 {
1418                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1419                         DeleteFile (path);
1420
1421                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1422                                 stream.Write (new byte[0], 1, -1);
1423                         }
1424                 }
1425
1426                 [Test]
1427                 [ExpectedException (typeof (ArgumentException))]
1428                 public void Write_CountOverflow ()
1429                 {
1430                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1431                         DeleteFile (path);
1432
1433                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1434                                 stream.Write (new byte[0], 1, Int32.MaxValue);
1435                         }
1436                 }
1437
1438                 [Test]
1439                 [ExpectedException (typeof (ArgumentException))]
1440                 public void Seek_InvalidSeekOrigin ()
1441                 {
1442                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1443                         DeleteFile (path);
1444
1445                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1446                                 stream.Seek (0, (SeekOrigin) (-1));
1447                         }
1448                 }
1449
1450 #if !TARGET_JVM // No support IntPtr file handles under TARGET_JVM
1451                 [Test]
1452                 [ExpectedException (typeof (ArgumentException))]
1453                 public void Constructor_InvalidFileHandle ()
1454                 {
1455                         new FileStream ((IntPtr) (-1L), FileAccess.Read);
1456                 }
1457 #endif // TARGET_JVM
1458
1459                 [Test]
1460                 public void PositionAfterSetLength ()
1461                 {
1462                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1463                         DeleteFile (path);
1464
1465                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1466                                 stream.SetLength (32);
1467                                 stream.Position = 32;
1468                                 stream.SetLength (16);
1469                                 Assert.AreEqual (16, stream.Position);
1470                         }
1471                 }
1472
1473                 [Test]
1474                 [ExpectedException (typeof (ObjectDisposedException))]
1475                 public void SetLength_Disposed ()
1476                 {
1477                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1478                         DeleteFile (path);
1479                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1480                         stream.Close ();
1481                         stream.SetLength (16);
1482                 }
1483
1484                 [Test]
1485                 [ExpectedException (typeof (ObjectDisposedException))]
1486                 public void Position_Disposed ()
1487                 {
1488                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1489                         DeleteFile (path);
1490                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1491                         stream.Close ();
1492                         stream.Position = 0;
1493                 }
1494
1495                 [Test]
1496                 [Category("TargetJvmNotSupported")] // Async IO not supported for TARGET_JVM
1497                 [ExpectedException (typeof (ObjectDisposedException))]
1498                 public void BeginRead_Disposed ()
1499                 {
1500                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1501                         DeleteFile (path);
1502                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read);
1503                         stream.Close ();
1504                         stream.EndRead (stream.BeginRead (new byte[8], 0, 8, null, null));
1505                 }
1506
1507                 [Test]
1508                 [Category("TargetJvmNotSupported")] // Async IO not supported for TARGET_JVM
1509                 [ExpectedException (typeof (ObjectDisposedException))]
1510                 public void BeginWrite_Disposed ()
1511                 {
1512                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1513                         DeleteFile (path);
1514                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1515                         stream.Close ();
1516                         stream.EndWrite (stream.BeginWrite (new byte[8], 0, 8, null, null));
1517                 }
1518
1519                 static IAsyncResult DoBeginWrite(Stream stream, ManualResetEvent mre, byte[] RandomBuffer)
1520                 {
1521                         return stream.BeginWrite (RandomBuffer, 0, RandomBuffer.Length, ar => {
1522                                 stream.EndWrite (ar);
1523
1524                                 // we don't supply an ManualResetEvent so this will throw an NRE on the second run
1525                                 // which nunit-console will ignore (but other test runners don't like that)
1526                                 if (mre == null)
1527                                         return;
1528
1529                                 DoBeginWrite (stream, null, RandomBuffer).AsyncWaitHandle.WaitOne ();
1530                                 mre.Set ();
1531                         }, null);
1532                 }
1533
1534                 [Test]
1535                 public void BeginWrite_Recursive ()
1536                 {
1537                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1538                         DeleteFile (path);
1539         
1540                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write)) {
1541                                 var mre = new ManualResetEvent (false); 
1542                                 var RandomBuffer = new byte[1024];                      
1543                                 DoBeginWrite (stream, mre, RandomBuffer);
1544                                 Assert.IsTrue (mre.WaitOne (5000), "#1");
1545                         }
1546                 }
1547
1548                 [Test]
1549                 [Category("TargetJvmNotSupported")] // File locking not supported for TARGET_JVM
1550                 [ExpectedException (typeof (ObjectDisposedException))]
1551                 public void Lock_Disposed ()
1552                 {
1553                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1554                         DeleteFile (path);
1555                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1556                         stream.Close ();
1557                         stream.Lock (0, 1);
1558                 }
1559
1560                 [Test]
1561                 [Category("TargetJvmNotSupported")] // File locking not supported for TARGET_JVM
1562                 [ExpectedException (typeof (ObjectDisposedException))]
1563                 public void Unlock_Disposed ()
1564                 {
1565                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1566                         DeleteFile (path);
1567                         FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write);
1568                         stream.Close ();
1569                         stream.Unlock (0, 1);
1570                 }
1571
1572                 [Test]
1573                 public void ReadBytePastEndOfStream ()
1574                 {
1575                         string path = TempFolder + Path.DirectorySeparatorChar + "temp";
1576                         DeleteFile (path);
1577                         using (FileStream stream = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Read)) {
1578                                 stream.Seek (0, SeekOrigin.End);
1579                                 Assert.AreEqual (-1, stream.ReadByte ());
1580                                 stream.Close ();
1581                         }
1582                 }
1583
1584                 [Test]
1585                 [ExpectedException (typeof (NotSupportedException))]
1586                 public void SetLengthWithClosedBaseStream ()
1587                 {
1588                         string fn = Path.Combine (TempFolder, "temp");
1589                         try {
1590                                 FileStream fs = new FileStream (fn, FileMode.Create);
1591                                 BufferedStream bs = new BufferedStream (fs);
1592                                 fs.Close ();
1593
1594                                 bs.SetLength (1000);
1595                         } finally {
1596                                 File.Delete (fn);
1597                         }
1598                 }
1599
1600                 [Test]
1601                 public void LengthAfterWrite ()
1602                 {
1603                         string path = TempFolder + DSC + "oneofthefilescreated.txt";
1604                         FileStream fs = null;
1605                         DeleteFile (path);
1606                         try {
1607                                 fs = new FileStream (path, FileMode.CreateNew);
1608                                 fs.WriteByte (Convert.ToByte ('A'));
1609                                 byte [] buffer = Encoding.ASCII.GetBytes (" is a first character.");
1610                                 fs.Write (buffer, 0, buffer.Length);
1611                                 fs.Seek (0, SeekOrigin.Begin);
1612                                 char a = Convert.ToChar (fs.ReadByte ());
1613                                 Assert.AreEqual ('A', a, "#A1");
1614                                 Assert.AreEqual (23, fs.Length, "#A2");
1615                                 int nread = fs.Read (buffer, 0, 5);
1616                                 Assert.AreEqual (5, nread, "#A3");
1617                         } finally {
1618                                 if (fs != null)
1619                                         fs.Close ();
1620                                 DeleteFile (path);
1621                         }
1622                 }
1623
1624                 [Category("TargetJvmNotSupported")] // FileOptions.DeleteOnClose not supported for TARGET_JVM
1625                 [Test]
1626                 public void DeleteOnClose ()
1627                 {
1628                         string path = TempFolder + DSC + "created.txt";
1629                         DeleteFile (path);
1630                         FileStream fs = new FileStream (path, FileMode.CreateNew, FileAccess.Write, FileShare.None, 1024,
1631                                                         FileOptions.DeleteOnClose);
1632                         Assert.AreEqual (true, File.Exists (path), "DOC#1");
1633                         fs.Close ();
1634                         Assert.AreEqual (false, File.Exists (path), "DOC#2");
1635                         
1636                 }
1637
1638 #if !MOBILE
1639                 [Test]
1640                 public void WriteWithExposedHandle ()
1641                 {
1642                         string path = TempFolder + DSC + "exposed-handle.txt";
1643                         FileStream fs1 = null;
1644                         FileStream fs2 = null;
1645                         DeleteFile (path);
1646                         
1647                         try {
1648                                 fs1 = new FileStream (path, FileMode.Create);
1649                                 fs2 = new FileStream (fs1.SafeFileHandle, FileAccess.ReadWrite);
1650                                 fs1.WriteByte (Convert.ToByte ('H'));
1651                                 fs1.WriteByte (Convert.ToByte ('E'));
1652                                 fs1.WriteByte (Convert.ToByte ('L'));
1653                                 fs2.WriteByte (Convert.ToByte ('L'));
1654                                 fs2.WriteByte (Convert.ToByte ('O'));
1655                                 long fs1Pos = fs1.Position;
1656                                 fs1.Flush ();
1657                                 fs2.Flush (); 
1658                                 fs1.Close ();
1659                                 fs2.Close ();
1660
1661                                 var check = Encoding.ASCII.GetString (File.ReadAllBytes (path));
1662                                 Assert.AreEqual ("HELLO", check, "EXPOSED#1");
1663                                 Assert.AreEqual (5, fs1Pos, "EXPOSED#2");
1664                         } finally {
1665                                 if (fs1 != null)
1666                                         fs1.Close ();
1667                                 if (fs2 != null)
1668                                         fs2.Close ();
1669                                 DeleteFile (path);
1670                         }
1671                 }
1672 #endif
1673         }
1674 }