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