View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2;
18  
19  import static org.junit.jupiter.api.Assertions.assertThrows;
20  
21  import java.io.OutputStream;
22  import java.nio.charset.StandardCharsets;
23  import java.util.ArrayList;
24  import java.util.HashSet;
25  import java.util.Objects;
26  import java.util.Set;
27  
28  import org.junit.Test;
29  import org.junit.jupiter.api.Assertions;
30  
31  /**
32   * File system test that check that a file system can be modified.
33   */
34  public class ProviderWriteTests extends AbstractProviderTestCase {
35  
36      /**
37       * A test listener.
38       */
39      private static class TestListener implements FileListener {
40          private static final Object CREATE = "create";
41          private static final Object DELETE = "delete";
42          private static final Object CHANGED = "changed";
43          private final FileObject file;
44          private final ArrayList<Object> events = new ArrayList<>();
45  
46          public TestListener(final FileObject file) {
47              this.file = file;
48          }
49  
50          public void addCreateEvent() {
51              events.add(CREATE);
52          }
53  
54          public void addDeleteEvent() {
55              events.add(DELETE);
56          }
57  
58          public void assertFinished() {
59              assertEquals("Missing event", 0, events.size());
60          }
61  
62          @Override
63          public void fileChanged(final FileChangeEvent event) throws Exception {
64              assertFalse("Unexpected changed event", events.isEmpty());
65              assertSame("Expecting a changed event", CHANGED, events.remove(0));
66              assertEquals(Objects.toString(file), file, event.getFileObject());
67              try {
68                  assertFalse(Objects.toString(file), file.exists());
69              } catch (final FileSystemException e) {
70                  fail();
71              }
72          }
73  
74          /**
75           * Called when a file is created.
76           */
77          @Override
78          public void fileCreated(final FileChangeEvent event) {
79              assertFalse("Unexpected create event", events.isEmpty());
80              assertSame("Expecting a create event", CREATE, events.remove(0));
81              assertEquals(Objects.toString(file), file, event.getFileObject());
82              try {
83                  assertTrue(Objects.toString(file), file.exists());
84              } catch (final FileSystemException e) {
85                  fail();
86              }
87          }
88  
89          /**
90           * Called when a file is deleted.
91           */
92          @Override
93          public void fileDeleted(final FileChangeEvent event) {
94              assertFalse("Unexpected delete event", events.isEmpty());
95              assertSame("Expecting a delete event", DELETE, events.remove(0));
96              assertEquals(Objects.toString(file), file, event.getFileObject());
97              try {
98                  assertFalse(Objects.toString(file), file.exists());
99              } catch (final FileSystemException e) {
100                 fail();
101             }
102         }
103     }
104 
105     /**
106      * Ensures the names of a set of files match an expected set.
107      */
108     private void assertSameFileSet(final Set<String> names, final FileObject[] files) {
109         // Make sure the sets are the same length
110         assertEquals(names.size(), files.length);
111 
112         // Check for unexpected names
113         for (final FileObject file : files) {
114             assertTrue(names.contains(file.getName().getBaseName()));
115         }
116     }
117 
118     /**
119      * Sets up a scratch folder for the test to use.
120      */
121     protected FileObject createScratchFolder() throws Exception {
122         final FileObject scratchFolder = getWriteFolder();
123 
124         // Make sure the test folder is empty
125         scratchFolder.delete(Selectors.EXCLUDE_SELF);
126         scratchFolder.createFolder();
127 
128         return scratchFolder;
129     }
130 
131     protected FileObject getReadFolderDir1() throws FileSystemException {
132         return getReadFolder().resolveFile("dir1");
133     }
134 
135     /**
136      * Returns the capabilities required by the tests of this test case.
137      */
138     @Override
139     protected Capability[] getRequiredCapabilities() {
140         return new Capability[] { Capability.CREATE, Capability.DELETE, Capability.GET_TYPE, Capability.LIST_CHILDREN,
141                 Capability.READ_CONTENT, Capability.WRITE_CONTENT };
142     }
143 
144     /**
145      * Tests overwriting a file on the same file system.
146      */
147     @Test
148     public void testCopyFromOverwriteSameFileSystem() throws Exception {
149         final FileObject scratchFolder = createScratchFolder();
150 
151         // Create direct child of the test folder
152         final FileObject file = scratchFolder.resolveFile("file1.txt");
153         assertFalse(file.exists());
154 
155         // Create the source file
156         final String content = "Here is some sample content for the file.  Blah Blah Blah.";
157         try (OutputStream os = file.getContent().getOutputStream()) {
158             os.write(content.getBytes(StandardCharsets.UTF_8));
159         }
160 
161         assertSameContent(content, file);
162 
163         // Make sure we can copy the new file to another file on the same filesystem
164         final FileObject fileCopy = scratchFolder.resolveFile("file1copy.txt");
165         assertFalse(fileCopy.exists());
166         fileCopy.copyFrom(file, Selectors.SELECT_SELF);
167 
168         assertSameContent(content, fileCopy);
169 
170         // Make sure we can copy the same new file to the same target file on the same filesystem
171         assertTrue(fileCopy.exists());
172         fileCopy.copyFrom(file, Selectors.SELECT_SELF);
173 
174         assertSameContent(content, fileCopy);
175     }
176 
177     /**
178      * Tests file copy to and from the same file system type. This was a problem w/ FTP.
179      */
180     @Test
181     public void testCopySameFileSystem() throws Exception {
182         final FileObject scratchFolder = createScratchFolder();
183 
184         // Create direct child of the test folder
185         final FileObject file = scratchFolder.resolveFile("file1.txt");
186         assertFalse(file.exists());
187 
188         // Create the source file
189         final String content = "Here is some sample content for the file.  Blah Blah Blah.";
190         try (OutputStream os = file.getContent().getOutputStream()) {
191             os.write(content.getBytes(StandardCharsets.UTF_8));
192         }
193 
194         assertSameContent(content, file);
195 
196         // Make sure we can copy the new file to another file on the same filesystem
197         final FileObject fileCopy = scratchFolder.resolveFile("file1copy.txt");
198         assertFalse(fileCopy.exists());
199         fileCopy.copyFrom(file, Selectors.SELECT_SELF);
200 
201         assertSameContent(content, fileCopy);
202     }
203 
204     /**
205      * Tests create-delete-create-a-file sequence on the same file system.
206      */
207     @Test
208     public void testCreateDeleteCreateSameFileSystem() throws Exception {
209         final FileObject scratchFolder = createScratchFolder();
210 
211         // Create direct child of the test folder
212         final FileObject file = scratchFolder.resolveFile("file1.txt");
213         assertFalse(file.exists());
214 
215         // Create the source file
216         final String content = "Here is some sample content for the file.  Blah Blah Blah.";
217         try (OutputStream os = file.getContent().getOutputStream()) {
218             os.write(content.getBytes(StandardCharsets.UTF_8));
219         }
220 
221         assertSameContent(content, file);
222 
223         // Make sure we can copy the new file to another file on the same filesystem
224         final FileObject fileCopy = scratchFolder.resolveFile("file1copy.txt");
225         assertFalse(fileCopy.exists());
226         fileCopy.copyFrom(file, Selectors.SELECT_SELF);
227 
228         assertSameContent(content, fileCopy);
229 
230         // Delete the file.
231         assertTrue(fileCopy.exists());
232         assertTrue(fileCopy.delete());
233 
234         // Make sure we can copy the same new file to the same target file on the same filesystem
235         assertFalse(fileCopy.exists());
236         fileCopy.copyFrom(file, Selectors.SELECT_SELF);
237 
238         assertSameContent(content, fileCopy);
239     }
240 
241     /*
242       Tests concurrent read and write on the same file fails.
243      */
244     /*
245      * imario@apache.org leave this to some sort of LockManager public void testConcurrentReadWrite() throws Exception {
246      * final FileObject scratchFolder = createScratchFolder();
247      *
248      * final FileObject file = scratchFolder.resolveFile("file1.txt"); file.createFile();
249      *
250      * // Start reading from the file final InputStream instr = file.getContent().getInputStream();
251      *
252      * try { // Try to write to the file file.getContent().getOutputStream(); fail(); } catch (final FileSystemException
253      * e) { // Check error message assertSameMessage("vfs.provider/write-in-use.error", file, e); } finally {
254      * instr.close(); } }
255      */
256 
257     /*
258       Tests concurrent writes on the same file fails.
259      */
260     /*
261      * imario@apache.org leave this to some sort of LockManager public void testConcurrentWrite() throws Exception {
262      * final FileObject scratchFolder = createScratchFolder();
263      *
264      * final FileObject file = scratchFolder.resolveFile("file1.txt"); file.createFile();
265      *
266      * // Start writing to the file final OutputStream outstr = file.getContent().getOutputStream(); final String
267      * testContent = "some content"; try { // Write some content to the first stream
268      * outstr.write(testContent.getBytes());
269      *
270      * // Try to open another output stream file.getContent().getOutputStream(); fail(); } catch (final
271      * FileSystemException e) { // Check error message assertSameMessage("vfs.provider/write-in-use.error", file, e); }
272      * finally { outstr.close(); }
273      *
274      * // Make sure that the content written to the first stream is actually applied assertSameContent(testContent,
275      * file); }
276      */
277 
278     /**
279      * Tests deletion.
280      */
281     @Test
282     public void testDelete() throws Exception {
283         // Set up the test structure
284         final FileObject folder = createScratchFolder();
285         folder.resolveFile("file1.txt").createFile();
286         folder.resolveFile("file%25.txt").createFile();
287         folder.resolveFile("emptydir").createFolder();
288         folder.resolveFile("dir1/file1.txt").createFile();
289         folder.resolveFile("dir1/dir2/file2.txt").createFile();
290 
291         // Delete a file
292         FileObject file = folder.resolveFile("file1.txt");
293         assertTrue(file.exists());
294         file.deleteAll();
295         assertFalse(file.exists());
296 
297         // Delete a special name file
298         file = folder.resolveFile("file%25.txt");
299         assertTrue(file.exists());
300         file.deleteAll();
301         assertFalse(file.exists());
302 
303         // Delete an empty folder
304         file = folder.resolveFile("emptydir");
305         assertTrue(file.exists());
306         file.deleteAll();
307         assertFalse(file.exists());
308 
309         // Recursive delete
310         file = folder.resolveFile("dir1");
311         final FileObject file2 = file.resolveFile("dir2/file2.txt");
312         assertTrue(file.exists());
313         assertTrue(file2.exists());
314         file.deleteAll();
315         assertFalse(file.exists());
316         assertFalse(file2.exists());
317 
318         // Delete a file that does not exist
319         file = folder.resolveFile("some-folder/some-file");
320         assertFalse(file.exists());
321         file.deleteAll();
322         assertFalse(file.exists());
323     }
324 
325     /**
326      * Tests deletion.
327      */
328     @Test
329     public void testDeleteAllDescendants() throws Exception {
330         // Set up the test structure
331         final FileObject folder = createScratchFolder();
332         folder.resolveFile("file1.txt").createFile();
333         folder.resolveFile("file%25.txt").createFile();
334         folder.resolveFile("emptydir").createFolder();
335         folder.resolveFile("dir1/file1.txt").createFile();
336         folder.resolveFile("dir1/dir2/file2.txt").createFile();
337 
338         // Delete a file
339         FileObject file = folder.resolveFile("file1.txt");
340         assertTrue(file.exists());
341         file.deleteAll();
342         assertFalse(file.exists());
343 
344         // Delete a special name file
345         file = folder.resolveFile("file%25.txt");
346         assertTrue(file.exists());
347         file.deleteAll();
348         assertFalse(file.exists());
349 
350         // Delete an empty folder
351         file = folder.resolveFile("emptydir");
352         assertTrue(file.exists());
353         file.deleteAll();
354         assertFalse(file.exists());
355 
356         // Recursive delete
357         file = folder.resolveFile("dir1");
358         final FileObject file2 = file.resolveFile("dir2/file2.txt");
359         assertTrue(file.exists());
360         assertTrue(file2.exists());
361         file.deleteAll();
362         assertFalse(file.exists());
363         assertFalse(file2.exists());
364 
365         // Delete a file that does not exist
366         file = folder.resolveFile("some-folder/some-file");
367         assertFalse(file.exists());
368         file.deleteAll();
369         assertFalse(file.exists());
370     }
371 
372     /**
373      * Tests file creation.
374      */
375     @Test
376     public void testFileCreate() throws Exception {
377         final FileObject scratchFolder = createScratchFolder();
378 
379         // Create direct child of the test folder
380         FileObject file = scratchFolder.resolveFile("file1.txt");
381         assertFalse(file.exists());
382         file.createFile();
383         assertTrue(file.exists());
384         assertSame(FileType.FILE, file.getType());
385         assertTrue(file.isFile());
386         assertEquals(0, file.getContent().getSize());
387         assertTrue(file.getContent().isEmpty());
388         assertFalse(file.isHidden());
389         assertFalse(file.isSymbolicLink());
390         assertTrue(file.isReadable());
391         assertTrue(file.isWriteable());
392 
393         // Create direct child of the test folder - special name
394         file = scratchFolder.resolveFile("file1%25.txt");
395         assertFalse(file.exists());
396         file.createFile();
397         assertTrue(file.exists());
398         assertSame(FileType.FILE, file.getType());
399         assertTrue(file.isFile());
400         assertEquals(0, file.getContent().getSize());
401         assertFalse(file.isHidden());
402         assertTrue(file.isReadable());
403         assertTrue(file.isWriteable());
404 
405         // Create a descendant, where the intermediate folders don't exist
406         file = scratchFolder.resolveFile("dir1/dir1/file1.txt");
407         assertFalse(file.exists());
408         assertFalse(file.getParent().exists());
409         assertFalse(file.getParent().getParent().exists());
410         file.createFile();
411         assertTrue(file.exists());
412         assertSame(FileType.FILE, file.getType());
413         assertTrue(file.isFile());
414         assertEquals(0, file.getContent().getSize());
415         assertTrue(file.getParent().exists());
416         assertTrue(file.getParent().getParent().exists());
417         assertFalse(file.getParent().isHidden());
418         assertFalse(file.getParent().getParent().isHidden());
419 
420         // Test creating a file that already exists
421         assertTrue(file.exists());
422         file.createFile();
423         assertTrue(file.exists());
424         assertTrue(file.isReadable());
425         assertTrue(file.isWriteable());
426     }
427 
428     /**
429      * Tests file/folder creation with mismatched types.
430      */
431     @Test
432     public void testFileCreateMismatched() throws Exception {
433         final FileObject scratchFolder = createScratchFolder();
434 
435         // Create a test file and folder
436         final FileObject file = scratchFolder.resolveFile("dir1/file1.txt");
437         file.createFile();
438         assertEquals(FileType.FILE, file.getType());
439         assertTrue(file.isFile());
440 
441         final FileObject folder = scratchFolder.resolveFile("dir1/dir2");
442         folder.createFolder();
443         assertEquals(FileType.FOLDER, folder.getType());
444         assertTrue(folder.isFolder());
445 
446         // Attempt to create a file that already exists as a folder
447         assertThrows(FileSystemException.class, () -> folder.createFile());
448 
449         // Attempt to create a folder that already exists as a file
450         assertThrows(FileSystemException.class, () -> file.createFolder());
451 
452         // Attempt to create a folder as a child of a file
453         final FileObject folder2 = file.resolveFile("some-child");
454         assertThrows(FileSystemException.class, () -> folder2.createFolder());
455     }
456 
457     /**
458      * Tests folder creation.
459      */
460     @Test
461     public void testFolderCreate() throws Exception {
462         final FileObject scratchFolder = createScratchFolder();
463 
464         // Create direct child of the test folder
465         FileObject folder = scratchFolder.resolveFile("dir1");
466         assertFalse(folder.exists());
467         folder.createFolder();
468         assertTrue(folder.exists());
469         assertSame(FileType.FOLDER, folder.getType());
470         assertTrue(folder.isFolder());
471         assertEquals(0, folder.getChildren().length);
472 
473         // Create a descendant, where the intermediate folders don't exist
474         folder = scratchFolder.resolveFile("dir2/dir1/dir1");
475         assertFalse(folder.exists());
476         assertFalse(folder.getParent().exists());
477         assertFalse(folder.getParent().getParent().exists());
478         folder.createFolder();
479         assertTrue(folder.exists());
480         assertSame(FileType.FOLDER, folder.getType());
481         assertTrue(folder.isFolder());
482         assertEquals(0, folder.getChildren().length);
483         assertTrue(folder.getParent().exists());
484         assertTrue(folder.getParent().getParent().exists());
485 
486         // Test creating a folder that already exists
487         assertTrue(folder.exists());
488         folder.createFolder();
489     }
490 
491     /**
492      * Tests that test read folder is not hidden.
493      */
494     @Test
495     public void testFolderIsHidden() throws Exception {
496         final FileObject folder = getReadFolderDir1();
497         Assertions.assertFalse(folder.isHidden());
498     }
499 
500     /**
501      * Tests that test read folder is readable.
502      */
503     @Test
504     public void testFolderIsReadable() throws Exception {
505         final FileObject folder = getReadFolderDir1();
506         Assertions.assertTrue(folder.isReadable());
507     }
508 
509     /**
510      * Tests that test folder is writable.
511      */
512     @Test
513     public void testFolderIsWritable() throws Exception {
514         final FileObject folder = getWriteFolder().resolveFile("dir1");
515         Assertions.assertTrue(folder.isWriteable());
516     }
517 
518     /**
519      * Test that children are handled correctly by create and delete.
520      */
521     @Test
522     public void testListChildren() throws Exception {
523         final FileObject folder = createScratchFolder();
524         final HashSet<String> names = new HashSet<>();
525 
526         // Make sure the folder is empty
527         assertEquals(0, folder.getChildren().length);
528 
529         // Create a child folder
530         folder.resolveFile("dir1").createFolder();
531         names.add("dir1");
532         assertSameFileSet(names, folder.getChildren());
533 
534         // Create a child file
535         folder.resolveFile("file1.html").createFile();
536         names.add("file1.html");
537         assertSameFileSet(names, folder.getChildren());
538 
539         // Create a descendent
540         folder.resolveFile("dir2/file1.txt").createFile();
541         names.add("dir2");
542         assertSameFileSet(names, folder.getChildren());
543 
544         // Create a child file via an output stream
545         final OutputStream outstr = folder.resolveFile("file2.txt").getContent().getOutputStream();
546         outstr.close();
547         names.add("file2.txt");
548         assertSameFileSet(names, folder.getChildren());
549 
550         // Delete a child folder
551         folder.resolveFile("dir1").deleteAll();
552         names.remove("dir1");
553         assertSameFileSet(names, folder.getChildren());
554 
555         // Delete a child file
556         folder.resolveFile("file1.html").deleteAll();
557         names.remove("file1.html");
558         assertSameFileSet(names, folder.getChildren());
559 
560         // Recreate the folder
561         folder.deleteAll();
562         folder.createFolder();
563         assertEquals(0, folder.getChildren().length);
564     }
565 
566     /**
567      * Check listeners are notified of changes.
568      */
569     @Test
570     public void testListener() throws Exception {
571         final FileObject baseFile = createScratchFolder();
572 
573         final FileObject child = baseFile.resolveFile("newfile.txt");
574         assertFalse(child.exists());
575 
576         final FileSystem fs = baseFile.getFileSystem();
577         final TestListener listener = new TestListener(child);
578         fs.addListener(child, listener);
579         try {
580             // Create as a folder
581             listener.addCreateEvent();
582             child.createFolder();
583             listener.assertFinished();
584 
585             // Create the folder again. Should not get an event.
586             child.createFolder();
587 
588             // Delete
589             listener.addDeleteEvent();
590             child.delete();
591             listener.assertFinished();
592 
593             // Delete again. Should not get an event
594             child.delete();
595 
596             // Create as a file
597             listener.addCreateEvent();
598             child.createFile();
599             listener.assertFinished();
600 
601             // Create the file again. Should not get an event
602             child.createFile();
603 
604             listener.addDeleteEvent();
605             child.delete();
606 
607             // Create as a file, by writing to it.
608             listener.addCreateEvent();
609             child.getContent().getOutputStream().close();
610             listener.assertFinished();
611 
612             // Recreate the file by writing to it
613             child.getContent().getOutputStream().close();
614 
615             // Copy another file over the top
616             final FileObject otherChild = baseFile.resolveFile("folder1");
617             otherChild.createFolder();
618             listener.addDeleteEvent();
619             listener.addCreateEvent();
620             child.copyFrom(otherChild, Selectors.SELECT_SELF);
621             listener.assertFinished();
622 
623         } finally {
624             fs.removeListener(child, listener);
625         }
626     }
627 
628     /**
629      * Tests overwriting the file.
630      *
631      * See [VFS-807].
632      */
633     @Test
634     public void testOverwriteContent() throws Exception {
635         final FileObject scratchFolder = createScratchFolder();
636 
637         // Create direct child of the test folder
638         final FileObject file = scratchFolder.resolveFile("file1.txt");
639         assertFalse(file.exists());
640 
641         // Create the source file
642         final String content1 = "Here is some sample content for the file. Blah Blah Blah.";
643 
644         try (OutputStream os = file.getContent().getOutputStream()) {
645             os.write(content1.getBytes(StandardCharsets.UTF_8));
646         }
647         assertSameContent(content1, file);
648 
649         // VFS-807, part 1: verify that writing to the existing file overwrites its content!
650         // content2 must be shorter than content1
651         final String content2 = "0123456789 ABCD";
652 
653         try (OutputStream os = file.getContent().getOutputStream()) {
654             os.write(content2.getBytes(StandardCharsets.UTF_8));
655         }
656         assertSameContent(content2, file);
657     }
658 
659     /**
660      * Tests overwriting a file on the same file system.
661      */
662     @Test
663     public void testOverwriteSameFileSystem() throws Exception {
664         final FileObject scratchFolder = createScratchFolder();
665 
666         // Create direct child of the test folder
667         final FileObject file = scratchFolder.resolveFile("file1.txt");
668         assertFalse(file.exists());
669 
670         // Create the source file
671         final String content = "Here is some sample content for the file.  Blah Blah Blah.";
672         try (OutputStream os = file.getContent().getOutputStream()) {
673             os.write(content.getBytes(StandardCharsets.UTF_8));
674         }
675 
676         assertSameContent(content, file);
677 
678         // Make sure we can copy the new file to another file on the same file system
679         final FileObject fileCopy = scratchFolder.resolveFile("file1copy.txt");
680         assertFalse(fileCopy.exists());
681         file.getContent().write(fileCopy);
682 
683         assertSameContent(content, fileCopy);
684 
685         // Make sure we can copy the same new file to the same target file on the same file system
686         assertTrue(fileCopy.exists());
687         file.getContent().write(fileCopy);
688 
689         assertSameContent(content, fileCopy);
690 
691         // Make sure we can copy the same new file to the same target file on the same file system
692         assertTrue(fileCopy.exists());
693         file.getContent().write(fileCopy.getContent());
694 
695         assertSameContent(content, fileCopy);
696 
697         // Make sure we can copy the same new file to the same target file on the same file system
698         assertTrue(fileCopy.exists());
699         OutputStream outputStream = fileCopy.getContent().getOutputStream();
700         try {
701             file.getContent().write(outputStream);
702         } finally {
703             outputStream.close();
704         }
705         assertSameContent(content, fileCopy);
706 
707         // Make sure we can copy the same new file to the same target file on the same file system
708         assertTrue(fileCopy.exists());
709         outputStream = fileCopy.getContent().getOutputStream();
710         try {
711             file.getContent().write(outputStream, 1234);
712         } finally {
713             outputStream.close();
714         }
715         assertSameContent(content, fileCopy);
716     }
717 
718     /**
719      * Tests file write to and from the same file system type.
720      */
721     @Test
722     public void testWriteSameFileSystem() throws Exception {
723         final FileObject scratchFolder = createScratchFolder();
724 
725         // Create direct child of the test folder
726         final FileObject fileSource = scratchFolder.resolveFile("file1.txt");
727         assertFalse(fileSource.exists());
728 
729         // Create the source file
730         final String expectedString = "Here is some sample content for the file.  Blah Blah Blah.";
731         try (OutputStream expectedOutputStream = fileSource.getContent().getOutputStream()) {
732             expectedOutputStream.write(expectedString.getBytes(StandardCharsets.UTF_8));
733         }
734 
735         assertSameContent(expectedString, fileSource);
736 
737         // Make sure we can copy the new file to another file on the same filesystem
738         final FileObject fileTarget = scratchFolder.resolveFile("file1copy.txt");
739         assertFalse(fileTarget.exists());
740 
741         final FileContent contentSource = fileSource.getContent();
742         //
743         // Tests FileContent#write(FileContent)
744         contentSource.write(fileTarget.getContent());
745         assertSameContent(expectedString, fileTarget);
746         //
747         // Tests FileContent#write(OutputStream)
748         OutputStream outputStream = fileTarget.getContent().getOutputStream();
749         try {
750             contentSource.write(outputStream);
751         } finally {
752             outputStream.close();
753         }
754         assertSameContent(expectedString, fileTarget);
755         //
756         // Tests FileContent#write(OutputStream, int)
757         outputStream = fileTarget.getContent().getOutputStream();
758         try {
759             contentSource.write(outputStream, 1234);
760         } finally {
761             outputStream.close();
762         }
763         assertSameContent(expectedString, fileTarget);
764     }
765 
766 }