• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.io;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static java.nio.charset.StandardCharsets.US_ASCII;
21 import static java.nio.charset.StandardCharsets.UTF_16LE;
22 import static java.nio.charset.StandardCharsets.UTF_8;
23 import static org.junit.Assert.assertThrows;
24 
25 import com.google.common.collect.ImmutableList;
26 import com.google.common.hash.Hashing;
27 import com.google.common.primitives.Bytes;
28 import java.io.BufferedReader;
29 import java.io.BufferedWriter;
30 import java.io.ByteArrayOutputStream;
31 import java.io.File;
32 import java.io.FileNotFoundException;
33 import java.io.IOException;
34 import java.io.PrintWriter;
35 import java.io.RandomAccessFile;
36 import java.nio.ByteBuffer;
37 import java.nio.MappedByteBuffer;
38 import java.nio.channels.FileChannel.MapMode;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.List;
42 import java.util.Random;
43 import junit.framework.TestSuite;
44 
45 /**
46  * Unit test for {@link Files}.
47  *
48  * <p>Some methods are tested in separate files:
49  *
50  * <ul>
51  *   <li>{@link Files#fileTraverser()} is tested in {@link FilesFileTraverserTest}.
52  *   <li>{@link Files#createTempDir()} is tested in {@link FilesCreateTempDirTest}.
53  * </ul>
54  *
55  * @author Chris Nokleberg
56  */
57 
58 @SuppressWarnings("InlineMeInliner") // many tests of deprecated methods
59 public class FilesTest extends IoTestCase {
60 
61   @AndroidIncompatible // suites, ByteSourceTester (b/230620681)
suite()62   public static TestSuite suite() {
63     TestSuite suite = new TestSuite();
64     suite.addTest(
65         ByteSourceTester.tests(
66             "Files.asByteSource[File]", SourceSinkFactories.fileByteSourceFactory(), true));
67     suite.addTest(
68         ByteSinkTester.tests("Files.asByteSink[File]", SourceSinkFactories.fileByteSinkFactory()));
69     suite.addTest(
70         ByteSinkTester.tests(
71             "Files.asByteSink[File, APPEND]", SourceSinkFactories.appendingFileByteSinkFactory()));
72     suite.addTest(
73         CharSourceTester.tests(
74             "Files.asCharSource[File, Charset]",
75             SourceSinkFactories.fileCharSourceFactory(),
76             false));
77     suite.addTest(
78         CharSinkTester.tests(
79             "Files.asCharSink[File, Charset]", SourceSinkFactories.fileCharSinkFactory()));
80     suite.addTest(
81         CharSinkTester.tests(
82             "Files.asCharSink[File, Charset, APPEND]",
83             SourceSinkFactories.appendingFileCharSinkFactory()));
84     suite.addTestSuite(FilesTest.class);
85     return suite;
86   }
87 
testRoundTripSources()88   public void testRoundTripSources() throws Exception {
89     File asciiFile = getTestFile("ascii.txt");
90     ByteSource byteSource = Files.asByteSource(asciiFile);
91     assertSame(byteSource, byteSource.asCharSource(UTF_8).asByteSource(UTF_8));
92   }
93 
testToByteArray()94   public void testToByteArray() throws IOException {
95     File asciiFile = getTestFile("ascii.txt");
96     File i18nFile = getTestFile("i18n.txt");
97     assertTrue(Arrays.equals(ASCII.getBytes(US_ASCII), Files.toByteArray(asciiFile)));
98     assertTrue(Arrays.equals(I18N.getBytes(UTF_8), Files.toByteArray(i18nFile)));
99     assertTrue(Arrays.equals(I18N.getBytes(UTF_8), Files.asByteSource(i18nFile).read()));
100   }
101 
102   /** A {@link File} that provides a specialized value for {@link File#length()}. */
103   private static class BadLengthFile extends File {
104 
105     private final long badLength;
106 
BadLengthFile(File delegate, long badLength)107     public BadLengthFile(File delegate, long badLength) {
108       super(delegate.getPath());
109       this.badLength = badLength;
110     }
111 
112     @Override
length()113     public long length() {
114       return badLength;
115     }
116 
117     private static final long serialVersionUID = 0;
118   }
119 
testToString()120   public void testToString() throws IOException {
121     File asciiFile = getTestFile("ascii.txt");
122     File i18nFile = getTestFile("i18n.txt");
123     assertEquals(ASCII, Files.toString(asciiFile, US_ASCII));
124     assertEquals(I18N, Files.toString(i18nFile, UTF_8));
125     assertThat(Files.toString(i18nFile, US_ASCII)).isNotEqualTo(I18N);
126   }
127 
testWriteString()128   public void testWriteString() throws IOException {
129     File temp = createTempFile();
130     Files.write(I18N, temp, UTF_16LE);
131     assertEquals(I18N, Files.toString(temp, UTF_16LE));
132   }
133 
testWriteBytes()134   public void testWriteBytes() throws IOException {
135     File temp = createTempFile();
136     byte[] data = newPreFilledByteArray(2000);
137     Files.write(data, temp);
138     assertTrue(Arrays.equals(data, Files.toByteArray(temp)));
139 
140     assertThrows(NullPointerException.class, () -> Files.write(null, temp));
141   }
142 
testAppendString()143   public void testAppendString() throws IOException {
144     File temp = createTempFile();
145     Files.append(I18N, temp, UTF_16LE);
146     assertEquals(I18N, Files.toString(temp, UTF_16LE));
147     Files.append(I18N, temp, UTF_16LE);
148     assertEquals(I18N + I18N, Files.toString(temp, UTF_16LE));
149     Files.append(I18N, temp, UTF_16LE);
150     assertEquals(I18N + I18N + I18N, Files.toString(temp, UTF_16LE));
151   }
152 
testCopyToOutputStream()153   public void testCopyToOutputStream() throws IOException {
154     File i18nFile = getTestFile("i18n.txt");
155     ByteArrayOutputStream out = new ByteArrayOutputStream();
156     Files.copy(i18nFile, out);
157     assertEquals(I18N, out.toString("UTF-8"));
158   }
159 
testCopyToAppendable()160   public void testCopyToAppendable() throws IOException {
161     File i18nFile = getTestFile("i18n.txt");
162     StringBuilder sb = new StringBuilder();
163     Files.copy(i18nFile, UTF_8, sb);
164     assertEquals(I18N, sb.toString());
165   }
166 
testCopyFile()167   public void testCopyFile() throws IOException {
168     File i18nFile = getTestFile("i18n.txt");
169     File temp = createTempFile();
170     Files.copy(i18nFile, temp);
171     assertEquals(I18N, Files.toString(temp, UTF_8));
172   }
173 
testCopyEqualFiles()174   public void testCopyEqualFiles() throws IOException {
175     File temp1 = createTempFile();
176     File temp2 = file(temp1.getPath());
177     assertEquals(temp1, temp2);
178     Files.write(ASCII, temp1, UTF_8);
179     assertThrows(IllegalArgumentException.class, () -> Files.copy(temp1, temp2));
180     assertEquals(ASCII, Files.toString(temp1, UTF_8));
181   }
182 
testCopySameFile()183   public void testCopySameFile() throws IOException {
184     File temp = createTempFile();
185     Files.write(ASCII, temp, UTF_8);
186     assertThrows(IllegalArgumentException.class, () -> Files.copy(temp, temp));
187     assertEquals(ASCII, Files.toString(temp, UTF_8));
188   }
189 
testCopyIdenticalFiles()190   public void testCopyIdenticalFiles() throws IOException {
191     File temp1 = createTempFile();
192     Files.write(ASCII, temp1, UTF_8);
193     File temp2 = createTempFile();
194     Files.write(ASCII, temp2, UTF_8);
195     Files.copy(temp1, temp2);
196     assertEquals(ASCII, Files.toString(temp2, UTF_8));
197   }
198 
testEqual()199   public void testEqual() throws IOException {
200     File asciiFile = getTestFile("ascii.txt");
201     File i18nFile = getTestFile("i18n.txt");
202     assertFalse(Files.equal(asciiFile, i18nFile));
203     assertTrue(Files.equal(asciiFile, asciiFile));
204 
205     File temp = createTempFile();
206     Files.copy(asciiFile, temp);
207     assertTrue(Files.equal(asciiFile, temp));
208 
209     Files.copy(i18nFile, temp);
210     assertTrue(Files.equal(i18nFile, temp));
211 
212     Files.copy(asciiFile, temp);
213     RandomAccessFile rf = new RandomAccessFile(temp, "rw");
214     rf.writeByte(0);
215     rf.close();
216     assertEquals(asciiFile.length(), temp.length());
217     assertFalse(Files.equal(asciiFile, temp));
218 
219     assertTrue(Files.asByteSource(asciiFile).contentEquals(Files.asByteSource(asciiFile)));
220 
221     // 0-length files have special treatment (/proc, etc.)
222     assertTrue(Files.equal(asciiFile, new BadLengthFile(asciiFile, 0)));
223   }
224 
testNewReader()225   public void testNewReader() throws IOException {
226     File asciiFile = getTestFile("ascii.txt");
227     assertThrows(NullPointerException.class, () -> Files.newReader(asciiFile, null));
228 
229     assertThrows(NullPointerException.class, () -> Files.newReader(null, UTF_8));
230 
231     BufferedReader r = Files.newReader(asciiFile, US_ASCII);
232     try {
233       assertEquals(ASCII, r.readLine());
234     } finally {
235       r.close();
236     }
237   }
238 
testNewWriter()239   public void testNewWriter() throws IOException {
240     File temp = createTempFile();
241     assertThrows(NullPointerException.class, () -> Files.newWriter(temp, null));
242 
243     assertThrows(NullPointerException.class, () -> Files.newWriter(null, UTF_8));
244 
245     BufferedWriter w = Files.newWriter(temp, UTF_8);
246     try {
247       w.write(I18N);
248     } finally {
249       w.close();
250     }
251 
252     File i18nFile = getTestFile("i18n.txt");
253     assertTrue(Files.equal(i18nFile, temp));
254   }
255 
testTouch()256   public void testTouch() throws IOException {
257     File temp = createTempFile();
258     assertTrue(temp.exists());
259     assertTrue(temp.delete());
260     assertFalse(temp.exists());
261     Files.touch(temp);
262     assertTrue(temp.exists());
263     Files.touch(temp);
264     assertTrue(temp.exists());
265 
266     assertThrows(
267         IOException.class,
268         () ->
269             Files.touch(
270                 new File(temp.getPath()) {
271                   @Override
272                   public boolean setLastModified(long t) {
273                     return false;
274                   }
275 
276                   private static final long serialVersionUID = 0;
277                 }));
278   }
279 
testTouchTime()280   public void testTouchTime() throws IOException {
281     File temp = createTempFile();
282     assertTrue(temp.exists());
283     temp.setLastModified(0);
284     assertEquals(0, temp.lastModified());
285     Files.touch(temp);
286     assertThat(temp.lastModified()).isNotEqualTo(0);
287   }
288 
testCreateParentDirs_root()289   public void testCreateParentDirs_root() throws IOException {
290     File file = root();
291     assertNull(file.getParentFile());
292     assertNull(file.getCanonicalFile().getParentFile());
293     Files.createParentDirs(file);
294   }
295 
testCreateParentDirs_relativePath()296   public void testCreateParentDirs_relativePath() throws IOException {
297     File file = file("nonexistent.file");
298     assertNull(file.getParentFile());
299     assertNotNull(file.getCanonicalFile().getParentFile());
300     Files.createParentDirs(file);
301   }
302 
testCreateParentDirs_noParentsNeeded()303   public void testCreateParentDirs_noParentsNeeded() throws IOException {
304     File file = file(getTempDir(), "nonexistent.file");
305     assertTrue(file.getParentFile().exists());
306     Files.createParentDirs(file);
307   }
308 
testCreateParentDirs_oneParentNeeded()309   public void testCreateParentDirs_oneParentNeeded() throws IOException {
310     File file = file(getTempDir(), "parent", "nonexistent.file");
311     File parent = file.getParentFile();
312     assertFalse(parent.exists());
313     try {
314       Files.createParentDirs(file);
315       assertTrue(parent.exists());
316     } finally {
317       assertTrue(parent.delete());
318     }
319   }
320 
testCreateParentDirs_multipleParentsNeeded()321   public void testCreateParentDirs_multipleParentsNeeded() throws IOException {
322     File file = file(getTempDir(), "grandparent", "parent", "nonexistent.file");
323     File parent = file.getParentFile();
324     File grandparent = parent.getParentFile();
325     assertFalse(grandparent.exists());
326     Files.createParentDirs(file);
327     assertTrue(parent.exists());
328   }
329 
testCreateParentDirs_nonDirectoryParentExists()330   public void testCreateParentDirs_nonDirectoryParentExists() throws IOException {
331     File parent = getTestFile("ascii.txt");
332     assertTrue(parent.isFile());
333     File file = file(parent, "foo");
334     assertThrows(IOException.class, () -> Files.createParentDirs(file));
335   }
336 
testMove()337   public void testMove() throws IOException {
338     File i18nFile = getTestFile("i18n.txt");
339     File temp1 = createTempFile();
340     File temp2 = createTempFile();
341 
342     Files.copy(i18nFile, temp1);
343     moveHelper(true, temp1, temp2);
344     assertTrue(Files.equal(temp2, i18nFile));
345   }
346 
testMoveViaCopy()347   public void testMoveViaCopy() throws IOException {
348     File i18nFile = getTestFile("i18n.txt");
349     File temp1 = createTempFile();
350     File temp2 = createTempFile();
351 
352     Files.copy(i18nFile, temp1);
353     moveHelper(true, new UnmovableFile(temp1, false, true), temp2);
354     assertTrue(Files.equal(temp2, i18nFile));
355   }
356 
testMoveFailures()357   public void testMoveFailures() throws IOException {
358     File temp1 = createTempFile();
359     File temp2 = createTempFile();
360 
361     moveHelper(false, new UnmovableFile(temp1, false, false), temp2);
362     moveHelper(
363         false, new UnmovableFile(temp1, false, false), new UnmovableFile(temp2, true, false));
364 
365     File asciiFile = getTestFile("ascii.txt");
366     assertThrows(IllegalArgumentException.class, () -> moveHelper(false, asciiFile, asciiFile));
367   }
368 
moveHelper(boolean success, File from, File to)369   private void moveHelper(boolean success, File from, File to) throws IOException {
370     try {
371       Files.move(from, to);
372       if (success) {
373         assertFalse(from.exists());
374         assertTrue(to.exists());
375       } else {
376         fail("expected exception");
377       }
378     } catch (IOException possiblyExpected) {
379       if (success) {
380         throw possiblyExpected;
381       }
382     }
383   }
384 
385   private static class UnmovableFile extends File {
386 
387     private final boolean canRename;
388     private final boolean canDelete;
389 
UnmovableFile(File file, boolean canRename, boolean canDelete)390     public UnmovableFile(File file, boolean canRename, boolean canDelete) {
391       super(file.getPath());
392       this.canRename = canRename;
393       this.canDelete = canDelete;
394     }
395 
396     @Override
renameTo(File to)397     public boolean renameTo(File to) {
398       return canRename && super.renameTo(to);
399     }
400 
401     @Override
delete()402     public boolean delete() {
403       return canDelete && super.delete();
404     }
405 
406     private static final long serialVersionUID = 0;
407   }
408 
testLineReading()409   public void testLineReading() throws IOException {
410     File temp = createTempFile();
411     assertNull(Files.readFirstLine(temp, UTF_8));
412     assertTrue(Files.readLines(temp, UTF_8).isEmpty());
413 
414     PrintWriter w = new PrintWriter(Files.newWriter(temp, UTF_8));
415     w.println("hello");
416     w.println("");
417     w.println(" world  ");
418     w.println("");
419     w.close();
420 
421     assertEquals("hello", Files.readFirstLine(temp, UTF_8));
422     assertEquals(ImmutableList.of("hello", "", " world  ", ""), Files.readLines(temp, UTF_8));
423 
424     assertTrue(temp.delete());
425   }
426 
testReadLines_withLineProcessor()427   public void testReadLines_withLineProcessor() throws IOException {
428     File temp = createTempFile();
429     LineProcessor<List<String>> collect =
430         new LineProcessor<List<String>>() {
431           List<String> collector = new ArrayList<>();
432 
433           @Override
434           public boolean processLine(String line) {
435             collector.add(line);
436             return true;
437           }
438 
439           @Override
440           public List<String> getResult() {
441             return collector;
442           }
443         };
444     assertThat(Files.readLines(temp, UTF_8, collect)).isEmpty();
445 
446     PrintWriter w = new PrintWriter(Files.newWriter(temp, UTF_8));
447     w.println("hello");
448     w.println("");
449     w.println(" world  ");
450     w.println("");
451     w.close();
452     Files.readLines(temp, UTF_8, collect);
453     assertThat(collect.getResult()).containsExactly("hello", "", " world  ", "").inOrder();
454 
455     LineProcessor<List<String>> collectNonEmptyLines =
456         new LineProcessor<List<String>>() {
457           List<String> collector = new ArrayList<>();
458 
459           @Override
460           public boolean processLine(String line) {
461             if (line.length() > 0) {
462               collector.add(line);
463             }
464             return true;
465           }
466 
467           @Override
468           public List<String> getResult() {
469             return collector;
470           }
471         };
472     Files.readLines(temp, UTF_8, collectNonEmptyLines);
473     assertThat(collectNonEmptyLines.getResult()).containsExactly("hello", " world  ").inOrder();
474 
475     assertTrue(temp.delete());
476   }
477 
testHash()478   public void testHash() throws IOException {
479     File asciiFile = getTestFile("ascii.txt");
480     File i18nFile = getTestFile("i18n.txt");
481 
482     String init = "d41d8cd98f00b204e9800998ecf8427e";
483     assertEquals(init, Hashing.md5().newHasher().hash().toString());
484 
485     String asciiHash = "e5df5a39f2b8cb71b24e1d8038f93131";
486     assertEquals(asciiHash, Files.hash(asciiFile, Hashing.md5()).toString());
487 
488     String i18nHash = "7fa826962ce2079c8334cd4ebf33aea4";
489     assertEquals(i18nHash, Files.hash(i18nFile, Hashing.md5()).toString());
490   }
491 
testMap()492   public void testMap() throws IOException {
493     // Test data
494     int size = 1024;
495     byte[] bytes = newPreFilledByteArray(size);
496 
497     // Setup
498     File file = createTempFile();
499     Files.write(bytes, file);
500 
501     // Test
502     MappedByteBuffer actual = Files.map(file);
503 
504     // Verify
505     ByteBuffer expected = ByteBuffer.wrap(bytes);
506     assertTrue("ByteBuffers should be equal.", expected.equals(actual));
507   }
508 
testMap_noSuchFile()509   public void testMap_noSuchFile() throws IOException {
510     // Setup
511     File file = createTempFile();
512     boolean deleted = file.delete();
513     assertTrue(deleted);
514 
515     // Test
516     assertThrows(FileNotFoundException.class, () -> Files.map(file));
517   }
518 
testMap_readWrite()519   public void testMap_readWrite() throws IOException {
520     // Test data
521     int size = 1024;
522     byte[] expectedBytes = new byte[size];
523     byte[] bytes = newPreFilledByteArray(1024);
524 
525     // Setup
526     File file = createTempFile();
527     Files.write(bytes, file);
528 
529     Random random = new Random();
530     random.nextBytes(expectedBytes);
531 
532     // Test
533     MappedByteBuffer map = Files.map(file, MapMode.READ_WRITE);
534     map.put(expectedBytes);
535 
536     // Verify
537     byte[] actualBytes = Files.toByteArray(file);
538     assertTrue(Arrays.equals(expectedBytes, actualBytes));
539   }
540 
testMap_readWrite_creates()541   public void testMap_readWrite_creates() throws IOException {
542     // Test data
543     int size = 1024;
544     byte[] expectedBytes = newPreFilledByteArray(1024);
545 
546     // Setup
547     File file = createTempFile();
548     boolean deleted = file.delete();
549     assertTrue(deleted);
550     assertFalse(file.exists());
551 
552     // Test
553     MappedByteBuffer map = Files.map(file, MapMode.READ_WRITE, size);
554     map.put(expectedBytes);
555 
556     // Verify
557     assertTrue(file.exists());
558     assertTrue(file.isFile());
559     assertEquals(size, file.length());
560     byte[] actualBytes = Files.toByteArray(file);
561     assertTrue(Arrays.equals(expectedBytes, actualBytes));
562   }
563 
testMap_readWrite_max_value_plus_1()564   public void testMap_readWrite_max_value_plus_1() throws IOException {
565     // Setup
566     File file = createTempFile();
567     // Test
568     assertThrows(
569         IllegalArgumentException.class,
570         () -> Files.map(file, MapMode.READ_WRITE, (long) Integer.MAX_VALUE + 1));
571   }
572 
testGetFileExtension()573   public void testGetFileExtension() {
574     assertEquals("txt", Files.getFileExtension(".txt"));
575     assertEquals("txt", Files.getFileExtension("blah.txt"));
576     assertEquals("txt", Files.getFileExtension("blah..txt"));
577     assertEquals("txt", Files.getFileExtension(".blah.txt"));
578     assertEquals("txt", Files.getFileExtension("/tmp/blah.txt"));
579     assertEquals("gz", Files.getFileExtension("blah.tar.gz"));
580     assertEquals("", Files.getFileExtension("/"));
581     assertEquals("", Files.getFileExtension("."));
582     assertEquals("", Files.getFileExtension(".."));
583     assertEquals("", Files.getFileExtension("..."));
584     assertEquals("", Files.getFileExtension("blah"));
585     assertEquals("", Files.getFileExtension("blah."));
586     assertEquals("", Files.getFileExtension(".blah."));
587     assertEquals("", Files.getFileExtension("/foo.bar/blah"));
588     assertEquals("", Files.getFileExtension("/foo/.bar/blah"));
589   }
590 
testGetNameWithoutExtension()591   public void testGetNameWithoutExtension() {
592     assertEquals("", Files.getNameWithoutExtension(".txt"));
593     assertEquals("blah", Files.getNameWithoutExtension("blah.txt"));
594     assertEquals("blah.", Files.getNameWithoutExtension("blah..txt"));
595     assertEquals(".blah", Files.getNameWithoutExtension(".blah.txt"));
596     assertEquals("blah", Files.getNameWithoutExtension("/tmp/blah.txt"));
597     assertEquals("blah.tar", Files.getNameWithoutExtension("blah.tar.gz"));
598     assertEquals("", Files.getNameWithoutExtension("/"));
599     assertEquals("", Files.getNameWithoutExtension("."));
600     assertEquals(".", Files.getNameWithoutExtension(".."));
601     assertEquals("..", Files.getNameWithoutExtension("..."));
602     assertEquals("blah", Files.getNameWithoutExtension("blah"));
603     assertEquals("blah", Files.getNameWithoutExtension("blah."));
604     assertEquals(".blah", Files.getNameWithoutExtension(".blah."));
605     assertEquals("blah", Files.getNameWithoutExtension("/foo.bar/blah"));
606     assertEquals("blah", Files.getNameWithoutExtension("/foo/.bar/blah"));
607   }
608 
testReadBytes()609   public void testReadBytes() throws IOException {
610     ByteProcessor<byte[]> processor =
611         new ByteProcessor<byte[]>() {
612           private final ByteArrayOutputStream out = new ByteArrayOutputStream();
613 
614           @Override
615           public boolean processBytes(byte[] buffer, int offset, int length) throws IOException {
616             if (length >= 0) {
617               out.write(buffer, offset, length);
618             }
619             return true;
620           }
621 
622           @Override
623           public byte[] getResult() {
624             return out.toByteArray();
625           }
626         };
627 
628     File asciiFile = getTestFile("ascii.txt");
629     byte[] result = Files.readBytes(asciiFile, processor);
630     assertEquals(Bytes.asList(Files.toByteArray(asciiFile)), Bytes.asList(result));
631   }
632 
testReadBytes_returnFalse()633   public void testReadBytes_returnFalse() throws IOException {
634     ByteProcessor<byte[]> processor =
635         new ByteProcessor<byte[]>() {
636           private final ByteArrayOutputStream out = new ByteArrayOutputStream();
637 
638           @Override
639           public boolean processBytes(byte[] buffer, int offset, int length) throws IOException {
640             if (length > 0) {
641               out.write(buffer, offset, 1);
642               return false;
643             } else {
644               return true;
645             }
646           }
647 
648           @Override
649           public byte[] getResult() {
650             return out.toByteArray();
651           }
652         };
653 
654     File asciiFile = getTestFile("ascii.txt");
655     byte[] result = Files.readBytes(asciiFile, processor);
656     assertEquals(1, result.length);
657   }
658 
testPredicates()659   public void testPredicates() throws IOException {
660     File asciiFile = getTestFile("ascii.txt");
661     File dir = asciiFile.getParentFile();
662     assertTrue(Files.isDirectory().apply(dir));
663     assertFalse(Files.isFile().apply(dir));
664 
665     assertFalse(Files.isDirectory().apply(asciiFile));
666     assertTrue(Files.isFile().apply(asciiFile));
667   }
668 
669   /** Returns a root path for the file system. */
root()670   private static File root() {
671     return File.listRoots()[0];
672   }
673 
674   /** Returns a {@code File} object for the given path parts. */
file(String first, String... more)675   private static File file(String first, String... more) {
676     return file(new File(first), more);
677   }
678 
679   /** Returns a {@code File} object for the given path parts. */
file(File first, String... more)680   private static File file(File first, String... more) {
681     // not very efficient, but should definitely be correct
682     File file = first;
683     for (String name : more) {
684       file = new File(file, name);
685     }
686     return file;
687   }
688 }
689