• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 package org.apache.commons.io.file;
19 
20 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertFalse;
23 import static org.junit.jupiter.api.Assertions.assertNotEquals;
24 import static org.junit.jupiter.api.Assertions.assertNotNull;
25 import static org.junit.jupiter.api.Assertions.assertNull;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
28 import static org.junit.jupiter.api.Assertions.assertTrue;
29 import static org.junit.jupiter.api.Assumptions.assumeFalse;
30 
31 import java.io.File;
32 import java.io.IOException;
33 import java.io.OutputStream;
34 import java.net.URI;
35 import java.net.URISyntaxException;
36 import java.net.URL;
37 import java.nio.charset.StandardCharsets;
38 import java.nio.file.DirectoryStream;
39 import java.nio.file.FileAlreadyExistsException;
40 import java.nio.file.FileSystem;
41 import java.nio.file.FileSystems;
42 import java.nio.file.Files;
43 import java.nio.file.LinkOption;
44 import java.nio.file.Path;
45 import java.nio.file.Paths;
46 import java.nio.file.attribute.DosFileAttributeView;
47 import java.nio.file.attribute.FileTime;
48 import java.nio.file.attribute.PosixFileAttributes;
49 import java.util.GregorianCalendar;
50 import java.util.HashMap;
51 import java.util.Iterator;
52 import java.util.Map;
53 
54 import org.apache.commons.io.FileUtils;
55 import org.apache.commons.io.FilenameUtils;
56 import org.apache.commons.io.filefilter.NameFileFilter;
57 import org.apache.commons.io.test.TestUtils;
58 import org.apache.commons.lang3.ArrayUtils;
59 import org.apache.commons.lang3.StringUtils;
60 import org.apache.commons.lang3.SystemUtils;
61 import org.junit.jupiter.api.Test;
62 
63 /**
64  * Tests {@link PathUtils}.
65  */
66 public class PathUtilsTest extends AbstractTempDirTest {
67 
68     private static final String STRING_FIXTURE = "Hello World";
69 
70     private static final byte[] BYTE_ARRAY_FIXTURE = STRING_FIXTURE.getBytes(StandardCharsets.UTF_8);
71 
72     private static final String TEST_JAR_NAME = "test.jar";
73 
74     private static final String TEST_JAR_PATH = "src/test/resources/org/apache/commons/io/test.jar";
75 
76     private static final String PATH_FIXTURE = "NOTICE.txt";
77 
78     /**
79      * Creates directory test fixtures.
80      * <ol>
81      * <li>tempDirPath/subdir</li>
82      * <li>tempDirPath/symlinked-dir -> tempDirPath/subdir</li>
83      * </ol>
84      *
85      * @return Path to tempDirPath/subdir
86      * @throws IOException if an I/O error occurs or the parent directory does not exist.
87      */
createTempSymlinkedRelativeDir()88     private Path createTempSymlinkedRelativeDir() throws IOException {
89         final Path targetDir = tempDirPath.resolve("subdir");
90         final Path symlinkDir = tempDirPath.resolve("symlinked-dir");
91         Files.createDirectory(targetDir);
92         Files.createSymbolicLink(symlinkDir, targetDir);
93         return symlinkDir;
94     }
95 
current()96     private Path current() {
97         return PathUtils.current();
98     }
99 
getLastModifiedMillis(final Path file)100     private Long getLastModifiedMillis(final Path file) throws IOException {
101         return Files.getLastModifiedTime(file).toMillis();
102     }
103 
getNonExistantPath()104     private Path getNonExistantPath() {
105         return Paths.get("/does not exist/for/certain");
106     }
107 
openArchive(final Path p, final boolean createNew)108     private FileSystem openArchive(final Path p, final boolean createNew) throws IOException {
109         if (createNew) {
110             final Map<String, String> env = new HashMap<>();
111             env.put("create", "true");
112             final URI fileUri = p.toAbsolutePath().toUri();
113             final URI uri = URI.create("jar:" + fileUri.toASCIIString());
114             return FileSystems.newFileSystem(uri, env, null);
115         }
116         return FileSystems.newFileSystem(p, (ClassLoader) null);
117     }
118 
setLastModifiedMillis(final Path file, final long millis)119     private void setLastModifiedMillis(final Path file, final long millis) throws IOException {
120         Files.setLastModifiedTime(file, FileTime.fromMillis(millis));
121     }
122 
123     @Test
testCopyDirectoryForDifferentFilesystemsWithAbsolutePath()124     public void testCopyDirectoryForDifferentFilesystemsWithAbsolutePath() throws IOException {
125         final Path archivePath = Paths.get(TEST_JAR_PATH);
126         try (FileSystem archive = openArchive(archivePath, false)) {
127             // relative jar -> absolute dir
128             Path sourceDir = archive.getPath("dir1");
129             PathUtils.copyDirectory(sourceDir, tempDirPath);
130             assertTrue(Files.exists(tempDirPath.resolve("f1")));
131 
132             // absolute jar -> absolute dir
133             sourceDir = archive.getPath("/next");
134             PathUtils.copyDirectory(sourceDir, tempDirPath);
135             assertTrue(Files.exists(tempDirPath.resolve("dir")));
136         }
137     }
138 
139     @Test
testCopyDirectoryForDifferentFilesystemsWithAbsolutePathReverse()140     public void testCopyDirectoryForDifferentFilesystemsWithAbsolutePathReverse() throws IOException {
141         try (FileSystem archive = openArchive(tempDirPath.resolve(TEST_JAR_NAME), true)) {
142             // absolute dir -> relative jar
143             Path targetDir = archive.getPath("target");
144             Files.createDirectory(targetDir);
145             final Path sourceDir = Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2").toAbsolutePath();
146             PathUtils.copyDirectory(sourceDir, targetDir);
147             assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));
148 
149             // absolute dir -> absolute jar
150             targetDir = archive.getPath("/");
151             PathUtils.copyDirectory(sourceDir, targetDir);
152             assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));
153         }
154     }
155 
156     @Test
testCopyDirectoryForDifferentFilesystemsWithRelativePath()157     public void testCopyDirectoryForDifferentFilesystemsWithRelativePath() throws IOException {
158         final Path archivePath = Paths.get(TEST_JAR_PATH);
159         try (FileSystem archive = openArchive(archivePath, false); final FileSystem targetArchive = openArchive(tempDirPath.resolve(TEST_JAR_NAME), true)) {
160             final Path targetDir = targetArchive.getPath("targetDir");
161             Files.createDirectory(targetDir);
162             // relative jar -> relative dir
163             Path sourceDir = archive.getPath("next");
164             PathUtils.copyDirectory(sourceDir, targetDir);
165             assertTrue(Files.exists(targetDir.resolve("dir")));
166 
167             // absolute jar -> relative dir
168             sourceDir = archive.getPath("/dir1");
169             PathUtils.copyDirectory(sourceDir, targetDir);
170             assertTrue(Files.exists(targetDir.resolve("f1")));
171         }
172     }
173 
174     @Test
testCopyDirectoryForDifferentFilesystemsWithRelativePathReverse()175     public void testCopyDirectoryForDifferentFilesystemsWithRelativePathReverse() throws IOException {
176         try (FileSystem archive = openArchive(tempDirPath.resolve(TEST_JAR_NAME), true)) {
177             // relative dir -> relative jar
178             Path targetDir = archive.getPath("target");
179             Files.createDirectory(targetDir);
180             final Path sourceDir = Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2");
181             PathUtils.copyDirectory(sourceDir, targetDir);
182             assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));
183 
184             // relative dir -> absolute jar
185             targetDir = archive.getPath("/");
186             PathUtils.copyDirectory(sourceDir, targetDir);
187             assertTrue(Files.exists(targetDir.resolve("dirs-a-file-size-1")));
188         }
189     }
190 
191     @Test
testCopyFile()192     public void testCopyFile() throws IOException {
193         final Path sourceFile = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1/file-size-1.bin");
194         final Path targetFile = PathUtils.copyFileToDirectory(sourceFile, tempDirPath);
195         assertTrue(Files.exists(targetFile));
196         assertEquals(Files.size(sourceFile), Files.size(targetFile));
197     }
198 
199     @Test
testCopyURL()200     public void testCopyURL() throws IOException {
201         final Path sourceFile = Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1/file-size-1.bin");
202         final URL url = new URL("file:///" + FilenameUtils.getPath(sourceFile.toAbsolutePath().toString()) + sourceFile.getFileName());
203         final Path targetFile = PathUtils.copyFileToDirectory(url, tempDirPath);
204         assertTrue(Files.exists(targetFile));
205         assertEquals(Files.size(sourceFile), Files.size(targetFile));
206     }
207 
208     @Test
testCreateDirectoriesAlreadyExists()209     public void testCreateDirectoriesAlreadyExists() throws IOException {
210         assertEquals(tempDirPath.getParent(), PathUtils.createParentDirectories(tempDirPath));
211     }
212 
213     @SuppressWarnings("resource") // FileSystems.getDefault() is a singleton
214     @Test
testCreateDirectoriesForRoots()215     public void testCreateDirectoriesForRoots() throws IOException {
216         for (final Path path : FileSystems.getDefault().getRootDirectories()) {
217             final Path parent = path.getParent();
218             assertNull(parent);
219             assertEquals(parent, PathUtils.createParentDirectories(path));
220         }
221     }
222 
223     @Test
testCreateDirectoriesForRootsLinkOptionNull()224     public void testCreateDirectoriesForRootsLinkOptionNull() throws IOException {
225         for (final File f : File.listRoots()) {
226             final Path path = f.toPath();
227             assertEquals(path.getParent(), PathUtils.createParentDirectories(path, (LinkOption) null));
228         }
229     }
230 
231     @Test
testCreateDirectoriesNew()232     public void testCreateDirectoriesNew() throws IOException {
233         assertEquals(tempDirPath, PathUtils.createParentDirectories(tempDirPath.resolve("child")));
234     }
235 
236     @Test
testCreateDirectoriesSymlink()237     public void testCreateDirectoriesSymlink() throws IOException {
238         final Path symlinkedDir = createTempSymlinkedRelativeDir();
239         final String leafDirName = "child";
240         final Path newDirFollowed = PathUtils.createParentDirectories(symlinkedDir.resolve(leafDirName), PathUtils.NULL_LINK_OPTION);
241         assertEquals(Files.readSymbolicLink(symlinkedDir), newDirFollowed);
242     }
243 
244     @Test
testCreateDirectoriesSymlinkClashing()245     public void testCreateDirectoriesSymlinkClashing() throws IOException {
246         final Path symlinkedDir = createTempSymlinkedRelativeDir();
247         assertThrowsExactly(FileAlreadyExistsException.class, () -> PathUtils.createParentDirectories(symlinkedDir.resolve("child")));
248     }
249 
250     @Test
testGetLastModifiedFileTime_File_Present()251     public void testGetLastModifiedFileTime_File_Present() throws IOException {
252         assertNotNull(PathUtils.getLastModifiedFileTime(current().toFile()));
253     }
254 
255     @Test
testGetLastModifiedFileTime_Path_Absent()256     public void testGetLastModifiedFileTime_Path_Absent() throws IOException {
257         assertNull(PathUtils.getLastModifiedFileTime(getNonExistantPath()));
258     }
259 
260     @Test
testGetLastModifiedFileTime_Path_FileTime_Absent()261     public void testGetLastModifiedFileTime_Path_FileTime_Absent() throws IOException {
262         final FileTime fromMillis = FileTime.fromMillis(0);
263         assertEquals(fromMillis, PathUtils.getLastModifiedFileTime(getNonExistantPath(), fromMillis));
264     }
265 
266     @Test
testGetLastModifiedFileTime_Path_Present()267     public void testGetLastModifiedFileTime_Path_Present() throws IOException {
268         assertNotNull(PathUtils.getLastModifiedFileTime(current()));
269     }
270 
271     @Test
testGetLastModifiedFileTime_URI_Present()272     public void testGetLastModifiedFileTime_URI_Present() throws IOException {
273         assertNotNull(PathUtils.getLastModifiedFileTime(current().toUri()));
274     }
275 
276     @Test
testGetLastModifiedFileTime_URL_Present()277     public void testGetLastModifiedFileTime_URL_Present() throws IOException, URISyntaxException {
278         assertNotNull(PathUtils.getLastModifiedFileTime(current().toUri().toURL()));
279     }
280 
281     @Test
testGetTempDirectory()282     public void testGetTempDirectory() {
283         final Path tempDirectory = Paths.get(System.getProperty("java.io.tmpdir"));
284         assertEquals(tempDirectory, PathUtils.getTempDirectory());
285     }
286 
287     @Test
testIsDirectory()288     public void testIsDirectory() throws IOException {
289         assertFalse(PathUtils.isDirectory(null));
290 
291         assertTrue(PathUtils.isDirectory(tempDirPath));
292         try (TempFile testFile1 = TempFile.create(tempDirPath, "prefix", null)) {
293             assertFalse(PathUtils.isDirectory(testFile1.get()));
294 
295             Path ref = null;
296             try (TempDirectory tempDir = TempDirectory.create(getClass().getCanonicalName())) {
297                 ref = tempDir.get();
298                 assertTrue(PathUtils.isDirectory(tempDir.get()));
299             }
300             assertFalse(PathUtils.isDirectory(ref));
301         }
302     }
303 
304     @Test
testIsPosix()305     public void testIsPosix() throws IOException {
306         boolean isPosix;
307         try {
308             Files.getPosixFilePermissions(current());
309             isPosix = true;
310         } catch (final UnsupportedOperationException e) {
311             isPosix = false;
312         }
313         assertEquals(isPosix, PathUtils.isPosix(current()));
314     }
315 
316     @Test
testIsRegularFile()317     public void testIsRegularFile() throws IOException {
318         assertFalse(PathUtils.isRegularFile(null));
319 
320         assertFalse(PathUtils.isRegularFile(tempDirPath));
321         try (TempFile testFile1 = TempFile.create(tempDirPath, "prefix", null)) {
322             assertTrue(PathUtils.isRegularFile(testFile1.get()));
323 
324             Files.delete(testFile1.get());
325             assertFalse(PathUtils.isRegularFile(testFile1.get()));
326         }
327     }
328 
329     @Test
testNewDirectoryStream()330     public void testNewDirectoryStream() throws Exception {
331         final PathFilter pathFilter = new NameFileFilter(PATH_FIXTURE);
332         try (DirectoryStream<Path> stream = PathUtils.newDirectoryStream(current(), pathFilter)) {
333             final Iterator<Path> iterator = stream.iterator();
334             final Path path = iterator.next();
335             assertEquals(PATH_FIXTURE, path.getFileName().toString());
336             assertFalse(iterator.hasNext());
337         }
338     }
339 
340     @Test
testNewOutputStreamExistingFileAppendFalse()341     public void testNewOutputStreamExistingFileAppendFalse() throws IOException {
342         testNewOutputStreamNewFile(false);
343         testNewOutputStreamNewFile(false);
344     }
345 
346     @Test
testNewOutputStreamExistingFileAppendTrue()347     public void testNewOutputStreamExistingFileAppendTrue() throws IOException {
348         testNewOutputStreamNewFile(true);
349         final Path file = writeToNewOutputStream(true);
350         assertArrayEquals(ArrayUtils.addAll(BYTE_ARRAY_FIXTURE, BYTE_ARRAY_FIXTURE), Files.readAllBytes(file));
351     }
352 
testNewOutputStreamNewFile(final boolean append)353     public void testNewOutputStreamNewFile(final boolean append) throws IOException {
354         final Path file = writeToNewOutputStream(append);
355         assertArrayEquals(BYTE_ARRAY_FIXTURE, Files.readAllBytes(file));
356     }
357 
358     @Test
testNewOutputStreamNewFileAppendFalse()359     public void testNewOutputStreamNewFileAppendFalse() throws IOException {
360         testNewOutputStreamNewFile(false);
361     }
362 
363     @Test
testNewOutputStreamNewFileAppendTrue()364     public void testNewOutputStreamNewFileAppendTrue() throws IOException {
365         testNewOutputStreamNewFile(true);
366     }
367 
368     @Test
testNewOutputStreamNewFileInsideExistingSymlinkedDir()369     public void testNewOutputStreamNewFileInsideExistingSymlinkedDir() throws IOException {
370         final Path symlinkDir = createTempSymlinkedRelativeDir();
371         final Path file = symlinkDir.resolve("test.txt");
372         try (OutputStream outputStream = PathUtils.newOutputStream(file, new LinkOption[] {})) {
373             // empty
374         }
375         try (OutputStream outputStream = PathUtils.newOutputStream(file, null)) {
376             // empty
377         }
378         try (OutputStream outputStream = PathUtils.newOutputStream(file, true)) {
379             // empty
380         }
381         try (OutputStream outputStream = PathUtils.newOutputStream(file, false)) {
382             // empty
383         }
384     }
385 
386     @Test
testReadAttributesPosix()387     public void testReadAttributesPosix() throws IOException {
388         boolean isPosix;
389         try {
390             Files.getPosixFilePermissions(current());
391             isPosix = true;
392         } catch (final UnsupportedOperationException e) {
393             isPosix = false;
394         }
395         assertEquals(isPosix, PathUtils.readAttributes(current(), PosixFileAttributes.class) != null);
396     }
397 
398     @Test
testReadStringEmptyFile()399     public void testReadStringEmptyFile() throws IOException {
400         final Path path = Paths.get("src/test/resources/org/apache/commons/io/test-file-empty.bin");
401         assertEquals(StringUtils.EMPTY, PathUtils.readString(path, StandardCharsets.UTF_8));
402         assertEquals(StringUtils.EMPTY, PathUtils.readString(path, null));
403     }
404 
405     @Test
testReadStringSimpleUtf8()406     public void testReadStringSimpleUtf8() throws IOException {
407         final Path path = Paths.get("src/test/resources/org/apache/commons/io/test-file-simple-utf8.bin");
408         final String expected = "ABC\r\n";
409         assertEquals(expected, PathUtils.readString(path, StandardCharsets.UTF_8));
410         assertEquals(expected, PathUtils.readString(path, null));
411     }
412 
413     @Test
testSetReadOnlyFile()414     public void testSetReadOnlyFile() throws IOException {
415         final Path resolved = tempDirPath.resolve("testSetReadOnlyFile.txt");
416         // Ask now, as we are allowed before editing parent permissions.
417         final boolean isPosix = PathUtils.isPosix(tempDirPath);
418 
419         // TEMP HACK
420         assumeFalse(SystemUtils.IS_OS_LINUX);
421 
422         PathUtils.writeString(resolved, "test", StandardCharsets.UTF_8);
423         final boolean readable = Files.isReadable(resolved);
424         final boolean writable = Files.isWritable(resolved);
425         final boolean regularFile = Files.isRegularFile(resolved);
426         final boolean executable = Files.isExecutable(resolved);
427         final boolean hidden = Files.isHidden(resolved);
428         final boolean directory = Files.isDirectory(resolved);
429         final boolean symbolicLink = Files.isSymbolicLink(resolved);
430         // Sanity checks
431         assertTrue(readable);
432         assertTrue(writable);
433         // Test A
434         PathUtils.setReadOnly(resolved, false);
435         assertTrue(Files.isReadable(resolved), "isReadable");
436         assertTrue(Files.isWritable(resolved), "isWritable");
437         // Again, shouldn't blow up.
438         PathUtils.setReadOnly(resolved, false);
439         assertTrue(Files.isReadable(resolved), "isReadable");
440         assertTrue(Files.isWritable(resolved), "isWritable");
441         //
442         assertEquals(regularFile, Files.isReadable(resolved));
443         assertEquals(executable, Files.isExecutable(resolved));
444         assertEquals(hidden, Files.isHidden(resolved));
445         assertEquals(directory, Files.isDirectory(resolved));
446         assertEquals(symbolicLink, Files.isSymbolicLink(resolved));
447         // Test B
448         PathUtils.setReadOnly(resolved, true);
449         if (isPosix) {
450             // On POSIX, now that the parent is not WX, the file is not readable.
451             assertFalse(Files.isReadable(resolved), "isReadable");
452         } else {
453             assertTrue(Files.isReadable(resolved), "isReadable");
454         }
455         assertFalse(Files.isWritable(resolved), "isWritable");
456         final DosFileAttributeView dosFileAttributeView = PathUtils.getDosFileAttributeView(resolved);
457         if (dosFileAttributeView != null) {
458             assertTrue(dosFileAttributeView.readAttributes().isReadOnly());
459         }
460         if (isPosix) {
461             assertFalse(Files.isReadable(resolved));
462         } else {
463             assertEquals(regularFile, Files.isReadable(resolved));
464         }
465         assertEquals(executable, Files.isExecutable(resolved));
466         assertEquals(hidden, Files.isHidden(resolved));
467         assertEquals(directory, Files.isDirectory(resolved));
468         assertEquals(symbolicLink, Files.isSymbolicLink(resolved));
469         //
470         PathUtils.setReadOnly(resolved, false);
471         PathUtils.deleteFile(resolved);
472     }
473 
474     @Test
testTouch()475     public void testTouch() throws IOException {
476         assertThrows(NullPointerException.class, () -> FileUtils.touch(null));
477 
478         final Path file = managedTempDirPath.resolve("touch.txt");
479         Files.deleteIfExists(file);
480         assertFalse(Files.exists(file), "Bad test: test file still exists");
481         PathUtils.touch(file);
482         assertTrue(Files.exists(file), "touch() created file");
483         try (OutputStream out = Files.newOutputStream(file)) {
484             assertEquals(0, Files.size(file), "Created empty file.");
485             out.write(0);
486         }
487         assertEquals(1, Files.size(file), "Wrote one byte to file");
488         final long y2k = new GregorianCalendar(2000, 0, 1).getTime().getTime();
489         setLastModifiedMillis(file, y2k); // 0L fails on Win98
490         assertEquals(y2k, getLastModifiedMillis(file), "Bad test: set lastModified set incorrect value");
491         final long nowMillis = System.currentTimeMillis();
492         PathUtils.touch(file);
493         assertEquals(1, Files.size(file), "FileUtils.touch() didn't empty the file.");
494         assertNotEquals(y2k, getLastModifiedMillis(file), "FileUtils.touch() changed lastModified");
495         final int delta = 3000;
496         assertTrue(getLastModifiedMillis(file) >= nowMillis - delta, "FileUtils.touch() changed lastModified to more than now-3s");
497         assertTrue(getLastModifiedMillis(file) <= nowMillis + delta, "FileUtils.touch() changed lastModified to less than now+3s");
498     }
499 
500     @Test
testWriteStringToFile1()501     public void testWriteStringToFile1() throws Exception {
502         final Path file = tempDirPath.resolve("write.txt");
503         PathUtils.writeString(file, "Hello /u1234", StandardCharsets.UTF_8);
504         final byte[] text = "Hello /u1234".getBytes(StandardCharsets.UTF_8);
505         TestUtils.assertEqualContent(text, file);
506     }
507 
508     /**
509      * Tests newOutputStream() here and don't use Files.write obviously.
510      */
writeToNewOutputStream(final boolean append)511     private Path writeToNewOutputStream(final boolean append) throws IOException {
512         final Path file = tempDirPath.resolve("test1.txt");
513         try (OutputStream os = PathUtils.newOutputStream(file, append)) {
514             os.write(BYTE_ARRAY_FIXTURE);
515         }
516         return file;
517     }
518 
519 }
520