@@ -108,6 +108,22 @@ pub fn stat<P: PathLike>(path: &P) -> Option<FileStat> {
108108 }
109109}
110110
111+ pub fn readdir < P : PathLike > ( path : & P ) -> Option < ~[ Path ] > {
112+ let readdir_result = unsafe {
113+ let io: * mut IoFactoryObject = Local :: unsafe_borrow ( ) ;
114+ ( * io) . fs_readdir ( path, 0 )
115+ } ;
116+ match readdir_result {
117+ Ok ( p) => {
118+ Some ( p)
119+ } ,
120+ Err ( ioerr) => {
121+ io_error:: cond. raise ( ioerr) ;
122+ None
123+ }
124+ }
125+ }
126+
111127/// Read-only view of file
112128pub struct FileReader { priv stream : FileStream }
113129
@@ -272,6 +288,18 @@ pub trait FileSystemInfo {
272288/// Represents passive information about a file (primarily exposed
273289/// via the `stat()` method. Also provides methods for opening
274290/// a file in various modes/permissions.
291+ ///
292+ /// # Example
293+ ///
294+ /// * Check if a file exists, reading from it if so
295+ ///
296+ /// let f = &Path("/some/file/path.txt");
297+ /// if f.exists() {
298+ /// let reader = f.open_reader(Open);
299+ /// let mut mem = [0u8, 8*64000];
300+ /// reader.read(mem);
301+ /// // ...
302+ /// }
275303pub trait FileInfo : FileSystemInfo {
276304 /// Whether the underlying implemention (be it a file path,
277305 /// or something else) points at a "regular file" on the FS. Will return
@@ -290,7 +318,7 @@ pub trait FileInfo : FileSystemInfo {
290318 match suppressed_stat ( || self . stat ( ) ) {
291319 Some ( s) => match s. is_file {
292320 true => open ( self . get_path ( ) , mode, access) ,
293- false => None // FIXME: raise condition, not a regular file..
321+ false => None
294322 } ,
295323 None => open ( self . get_path ( ) , mode, access)
296324 }
@@ -320,13 +348,16 @@ pub trait FileInfo : FileSystemInfo {
320348 }
321349}
322350
323- /// `FileSystemInfo` implementation for `Path`s
351+ /// `FileSystemInfo` implementation for `Path`s
324352impl FileSystemInfo for Path {
325353 fn get_path < ' a > ( & ' a self ) -> & ' a Path { self }
326354}
327- /// `FileInfo` implementation for `Path`s
355+ /// `FileInfo` implementation for `Path`s
328356impl FileInfo for Path { }
329357
358+ /// Passive information about a directory on the filesystem. Includes
359+ /// Convenience methods to iterate over a directory's contents (via `readdir`, as
360+ /// as `mkdir` and `rmdir` operations.
330361trait DirectoryInfo : FileSystemInfo {
331362 /// Whether the underlying implemention (be it a file path,
332363 /// or something else) points at a directory file" on the FS. Will return
@@ -368,8 +399,9 @@ trait DirectoryInfo : FileSystemInfo {
368399 let ioerr = IoError {
369400 kind : MismatchedFileTypeForOperation ,
370401 desc : "Cannot do rmdir() on a non-directory" ,
371- detail :
372- Some ( fmt ! ( "%s is a non-directory; can't rmdir it" , self . get_path( ) . to_str( ) ) )
402+ detail : Some ( fmt ! (
403+ "%s is a non-directory; can't rmdir it" ,
404+ self . get_path( ) . to_str( ) ) )
373405 } ;
374406 io_error:: cond. raise ( ioerr) ;
375407 }
@@ -383,14 +415,13 @@ trait DirectoryInfo : FileSystemInfo {
383415 } )
384416 }
385417 }
386- fn readdir ( & self ) -> ~ [ ~ str ] {
387- ~ [ ]
418+ fn readdir ( & self ) -> Option < ~ [ Path ] > {
419+ readdir ( self . get_path ( ) )
388420 }
389421 //fn get_subdirs(&self, filter: &str) -> ~[Path];
390422 //fn get_files(&self, filter: &str) -> ~[Path];
391423}
392424
393- /// FIXME: DOCS
394425impl DirectoryInfo for Path { }
395426
396427fn file_test_smoke_test_impl ( ) {
@@ -663,3 +694,41 @@ fn file_test_directoryinfo_check_exists_before_and_after_mkdir() {
663694 assert ! ( !dir. exists( ) ) ;
664695 }
665696}
697+
698+ #[ test]
699+ fn file_test_directoryinfo_readdir ( ) {
700+ use str;
701+ do run_in_mt_newsched_task {
702+ let dir = & Path ( "./tmp/di_readdir" ) ;
703+ dir. mkdir ( ) ;
704+ let prefix = "foo" ;
705+ for n in range ( 0 , 3 ) {
706+ let f = dir. push ( fmt ! ( "%d.txt" , n) ) ;
707+ let mut w = f. open_writer ( Create ) ;
708+ let msg_str = ( prefix + n. to_str ( ) . to_owned ( ) ) . to_owned ( ) ;
709+ let msg = msg_str. as_bytes ( ) ;
710+ w. write ( msg) ;
711+ }
712+ match dir. readdir ( ) {
713+ Some ( files) => {
714+ let mut mem = [ 0u8 , .. 4 ] ;
715+ for f in files. iter ( ) {
716+ {
717+ let n = f. filestem ( ) ;
718+ let mut r = f. open_reader ( Open ) ;
719+ r. read ( mem) ;
720+ let read_str = str:: from_utf8 ( mem) ;
721+ let expected = match n {
722+ Some ( n) => prefix+n,
723+ None => fail ! ( "really shouldn't happen.." )
724+ } ;
725+ assert ! ( expected == read_str) ;
726+ }
727+ f. unlink ( ) ;
728+ }
729+ } ,
730+ None => fail ! ( "shouldn't happen" )
731+ }
732+ dir. rmdir ( ) ;
733+ }
734+ }
0 commit comments