Skip to content

Commit 7adcc09

Browse files
author
Gary Gregory
committed
[IO-631] Add a CountingFileVisitor (as the basis for a forthcoming
DeletingFileVisitor).
1 parent 543fd81 commit 7adcc09

7 files changed

Lines changed: 176 additions & 0 deletions

File tree

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ The <action> type attribute can be add,update,fix,remove.
143143
<action issue="IO-630" dev="ggregory" type="update" due-to="Gary Gregory">
144144
Deprecate org.apache.commons.io.output.NullOutputStream.NullOutputStream() in favor of org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM.
145145
</action>
146+
<action issue="IO-631" dev="ggregory" type="add" due-to="Gary Gregory">
147+
Add a CountingFileVisitor (as the basis for a forthcoming DeletingFileVisitor).
148+
</action>
146149
</release>
147150

148151
<release version="2.6" date="2017-10-15" description="Java 7 required, Java 9 supported.">
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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 java.io.IOException;
21+
import java.nio.file.FileVisitResult;
22+
import java.nio.file.Files;
23+
import java.nio.file.Path;
24+
import java.nio.file.SimpleFileVisitor;
25+
import java.nio.file.attribute.BasicFileAttributes;
26+
import java.util.concurrent.atomic.AtomicLong;
27+
28+
/**
29+
* Counts files, directories, and sizes, as a visit proceeds.
30+
*/
31+
public class CountingFileVisitor extends SimpleFileVisitor<Path> {
32+
33+
private final AtomicLong byteCount = new AtomicLong();
34+
private final AtomicLong directoryCount = new AtomicLong();
35+
private final AtomicLong fileCount = new AtomicLong();
36+
37+
/**
38+
* Gets the byte count of visited files.
39+
*
40+
* @return the byte count of visited files.
41+
*/
42+
public long getByteCount() {
43+
return this.byteCount.get();
44+
}
45+
46+
/**
47+
* Gets the count of visited directories.
48+
*
49+
* @return the count of visited directories.
50+
*/
51+
public long getDirectoryCount() {
52+
return this.directoryCount.get();
53+
}
54+
55+
/**
56+
* Gets the count of visited files.
57+
*
58+
* @return the byte count of visited files.
59+
*/
60+
public long getFileCount() {
61+
return this.fileCount.get();
62+
}
63+
64+
@Override
65+
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
66+
directoryCount.incrementAndGet();
67+
return FileVisitResult.CONTINUE;
68+
}
69+
70+
@Override
71+
public String toString() {
72+
return String.format("%,d files in %,d directories for %,d bytes", Long.valueOf(fileCount.longValue()),
73+
Long.valueOf(directoryCount.longValue()), Long.valueOf(byteCount.longValue()));
74+
}
75+
76+
@Override
77+
public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
78+
if (Files.exists(file)) {
79+
fileCount.incrementAndGet();
80+
byteCount.addAndGet(attrs.size());
81+
}
82+
return FileVisitResult.CONTINUE;
83+
}
84+
85+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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 java.io.IOException;
21+
import java.nio.file.Files;
22+
import java.nio.file.Path;
23+
import java.nio.file.Paths;
24+
25+
import org.junit.jupiter.api.Assertions;
26+
import org.junit.jupiter.api.Test;
27+
28+
/**
29+
* Tests {@link CountingFileVisitor}.
30+
*/
31+
public class CountingFileVisitorTest {
32+
33+
/**
34+
* Tests an empty folder.
35+
*/
36+
@Test
37+
public void testEmptyFolder() throws IOException {
38+
final Path tempDirectory = Files.createTempDirectory(getClass().getCanonicalName());
39+
try {
40+
final CountingFileVisitor visitor = new CountingFileVisitor();
41+
Files.walkFileTree(tempDirectory, visitor);
42+
Assertions.assertEquals(1, visitor.getDirectoryCount());
43+
Assertions.assertEquals(0, visitor.getFileCount());
44+
Assertions.assertEquals(0, visitor.getByteCount());
45+
} finally {
46+
Files.delete(tempDirectory);
47+
}
48+
}
49+
50+
/**
51+
* Tests a directory with one file of size 0.
52+
*/
53+
@Test
54+
public void testFolders1FileSize0() throws IOException {
55+
final CountingFileVisitor visitor = new CountingFileVisitor();
56+
Files.walkFileTree(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-0"), visitor);
57+
Assertions.assertEquals(1, visitor.getDirectoryCount());
58+
Assertions.assertEquals(1, visitor.getFileCount());
59+
Assertions.assertEquals(0, visitor.getByteCount());
60+
}
61+
62+
/**
63+
* Tests a directory with one file of size 1.
64+
*/
65+
@Test
66+
public void testFolders1FileSize1() throws IOException {
67+
final CountingFileVisitor visitor = new CountingFileVisitor();
68+
Files.walkFileTree(Paths.get("src/test/resources/org/apache/commons/io/dirs-1-file-size-1"), visitor);
69+
Assertions.assertEquals(1, visitor.getDirectoryCount());
70+
Assertions.assertEquals(1, visitor.getFileCount());
71+
Assertions.assertEquals(1, visitor.getByteCount());
72+
}
73+
74+
/**
75+
* Tests a directory with two subdirectorys, each containing one file of size 1.
76+
*/
77+
@Test
78+
public void testFolders2FileSize2() throws IOException {
79+
final CountingFileVisitor visitor = new CountingFileVisitor();
80+
Files.walkFileTree(Paths.get("src/test/resources/org/apache/commons/io/dirs-2-file-size-2"), visitor);
81+
Assertions.assertEquals(3, visitor.getDirectoryCount());
82+
Assertions.assertEquals(2, visitor.getFileCount());
83+
Assertions.assertEquals(2, visitor.getByteCount());
84+
}
85+
}

src/test/resources/org/apache/commons/io/dirs-1-file-size-0/file-size-0.bin

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
a

0 commit comments

Comments
 (0)