< prev index next >

src/java.base/unix/classes/sun/nio/fs/UnixDirectoryStream.java

Print this page

 32 import java.io.IOException;
 33 import static sun.nio.fs.UnixNativeDispatcher.*;
 34 
 35 /**
 36  * Unix implementation of java.nio.file.DirectoryStream
 37  */
 38 
 39 class UnixDirectoryStream
 40     implements DirectoryStream<Path>
 41 {
 42     // path to directory when originally opened
 43     private final UnixPath dir;
 44 
 45     // directory pointer (returned by opendir)
 46     private final long dp;
 47 
 48     // filter (may be null)
 49     private final DirectoryStream.Filter<? super Path> filter;
 50 
 51     // used to coordinate closing of directory stream
 52     private final ReentrantReadWriteLock streamLock =
 53         new ReentrantReadWriteLock(true);
 54 
 55     // indicates if directory stream is open (synchronize on closeLock)
 56     private volatile boolean isClosed;
 57 
 58     // directory iterator
 59     private Iterator<Path> iterator;
 60 
 61     /**
 62      * Initializes a new instance
 63      */
 64     UnixDirectoryStream(UnixPath dir, long dp, DirectoryStream.Filter<? super Path> filter) {
 65         this.dir = dir;
 66         this.dp = dp;
 67         this.filter = filter;
 68     }
 69 
 70     protected final UnixPath directory() {
 71         return dir;
 72     }
 73 
 74     protected final Lock readLock() {
 75         return streamLock.readLock();

113         if (isClosed) {
114             throw new IllegalStateException("Directory stream is closed");
115         }
116         synchronized (this) {
117             if (iterator != null)
118                 throw new IllegalStateException("Iterator already obtained");
119             iterator = new UnixDirectoryIterator();
120             return iterator;
121         }
122     }
123 
124     @Override
125     public Iterator<Path> iterator() {
126         return iterator(this);
127     }
128 
129     /**
130      * Iterator implementation
131      */
132     private class UnixDirectoryIterator implements Iterator<Path> {


133         // true when at EOF
134         private boolean atEof;
135 
136         // next entry to return
137         private Path nextEntry;
138 
139         UnixDirectoryIterator() {
140             atEof = false;
141         }
142 
143         // Return true if file name is "." or ".."
144         private boolean isSelfOrParent(byte[] nameAsBytes) {
145             if (nameAsBytes[0] == '.') {
146                 if ((nameAsBytes.length == 1) ||
147                     (nameAsBytes.length == 2 && nameAsBytes[1] == '.')) {
148                     return true;
149                 }
150             }
151             return false;
152         }
153 
154         // Returns next entry (or null)
155         private Path readNextEntry() {
156             assert Thread.holdsLock(this);
157 
158             for (;;) {
159                 byte[] nameAsBytes = null;
160 
161                 // prevent close while reading
162                 readLock().lock();
163                 try {
164                     if (isOpen()) {
165                         nameAsBytes = readdir(dp);
166                     }
167                 } catch (UnixException x) {
168                     IOException ioe = x.asIOException(dir);
169                     throw new DirectoryIteratorException(ioe);
170                 } finally {
171                     readLock().unlock();
172                 }
173 
174                 // EOF
175                 if (nameAsBytes == null) {
176                     atEof = true;
177                     return null;
178                 }
179 
180                 // ignore "." and ".."
181                 if (!isSelfOrParent(nameAsBytes)) {
182                     Path entry = dir.resolve(nameAsBytes);
183 
184                     // return entry if no filter or filter accepts it
185                     try {
186                         if (filter == null || filter.accept(entry))
187                             return entry;
188                     } catch (IOException ioe) {
189                         throw new DirectoryIteratorException(ioe);
190                     }
191                 }
192             }
193         }
194 
195         @Override
196         public synchronized boolean hasNext() {
197             if (nextEntry == null && !atEof)
198                 nextEntry = readNextEntry();
199             return nextEntry != null;





200         }
201 
202         @Override
203         public synchronized Path next() {
204             Path result;
205             if (nextEntry == null && !atEof) {
206                 result = readNextEntry();
207             } else {
208                 result = nextEntry;
209                 nextEntry = null;








210             }
211             if (result == null)
212                 throw new NoSuchElementException();
213             return result;
214         }
215 
216         @Override
217         public void remove() {
218             throw new UnsupportedOperationException();
219         }
220     }
221 }

 32 import java.io.IOException;
 33 import static sun.nio.fs.UnixNativeDispatcher.*;
 34 
 35 /**
 36  * Unix implementation of java.nio.file.DirectoryStream
 37  */
 38 
 39 class UnixDirectoryStream
 40     implements DirectoryStream<Path>
 41 {
 42     // path to directory when originally opened
 43     private final UnixPath dir;
 44 
 45     // directory pointer (returned by opendir)
 46     private final long dp;
 47 
 48     // filter (may be null)
 49     private final DirectoryStream.Filter<? super Path> filter;
 50 
 51     // used to coordinate closing of directory stream
 52     private final ReentrantReadWriteLock streamLock = new ReentrantReadWriteLock();

 53 
 54     // indicates if directory stream is open
 55     private volatile boolean isClosed;
 56 
 57     // directory iterator
 58     private Iterator<Path> iterator;
 59 
 60     /**
 61      * Initializes a new instance
 62      */
 63     UnixDirectoryStream(UnixPath dir, long dp, DirectoryStream.Filter<? super Path> filter) {
 64         this.dir = dir;
 65         this.dp = dp;
 66         this.filter = filter;
 67     }
 68 
 69     protected final UnixPath directory() {
 70         return dir;
 71     }
 72 
 73     protected final Lock readLock() {
 74         return streamLock.readLock();

112         if (isClosed) {
113             throw new IllegalStateException("Directory stream is closed");
114         }
115         synchronized (this) {
116             if (iterator != null)
117                 throw new IllegalStateException("Iterator already obtained");
118             iterator = new UnixDirectoryIterator();
119             return iterator;
120         }
121     }
122 
123     @Override
124     public Iterator<Path> iterator() {
125         return iterator(this);
126     }
127 
128     /**
129      * Iterator implementation
130      */
131     private class UnixDirectoryIterator implements Iterator<Path> {
132         private final ReentrantLock iteratorLock = new ReentrantLock();
133 
134         // true when at EOF
135         private boolean atEof;
136 
137         // next entry to return
138         private Path nextEntry;
139 
140         UnixDirectoryIterator() {
141             atEof = false;
142         }
143 
144         // Return true if file name is "." or ".."
145         private boolean isSelfOrParent(byte[] nameAsBytes) {
146             if (nameAsBytes[0] == '.') {
147                 if ((nameAsBytes.length == 1) ||
148                     (nameAsBytes.length == 2 && nameAsBytes[1] == '.')) {
149                     return true;
150                 }
151             }
152             return false;
153         }
154 
155         // Returns next entry (or null)
156         private Path readNextEntry() {
157             assert iteratorLock.isHeldByCurrentThread();
158 
159             for (;;) {
160                 byte[] nameAsBytes = null;
161 
162                 // prevent close while reading
163                 readLock().lock();
164                 try {
165                     if (isOpen()) {
166                         nameAsBytes = readdir(dp);
167                     }
168                 } catch (UnixException x) {
169                     IOException ioe = x.asIOException(dir);
170                     throw new DirectoryIteratorException(ioe);
171                 } finally {
172                     readLock().unlock();
173                 }
174 
175                 // EOF
176                 if (nameAsBytes == null) {
177                     atEof = true;
178                     return null;
179                 }
180 
181                 // ignore "." and ".."
182                 if (!isSelfOrParent(nameAsBytes)) {
183                     Path entry = dir.resolve(nameAsBytes);
184 
185                     // return entry if no filter or filter accepts it
186                     try {
187                         if (filter == null || filter.accept(entry))
188                             return entry;
189                     } catch (IOException ioe) {
190                         throw new DirectoryIteratorException(ioe);
191                     }
192                 }
193             }
194         }
195 
196         @Override
197         public boolean hasNext() {
198             iteratorLock.tryLock();
199             try {
200                 if (nextEntry == null && !atEof)
201                     nextEntry = readNextEntry();
202                 return nextEntry != null;
203             } finally {
204                 iteratorLock.unlock();
205             }
206         }
207 
208         @Override
209         public Path next() {
210             iteratorLock.tryLock();
211             try {
212                 Path result;
213                 if (nextEntry == null && !atEof) {
214                     result = readNextEntry();
215                 } else {
216                     result = nextEntry;
217                     nextEntry = null;
218                 }
219                 if (result == null)
220                     throw new NoSuchElementException();
221                 return result;
222             } finally {
223                 iteratorLock.unlock();
224             }



225         }
226 
227         @Override
228         public void remove() {
229             throw new UnsupportedOperationException();
230         }
231     }
232 }
< prev index next >