Hello all,
I'm working on a specific part of my project where I need to load all files
from a given directory.
I started to work with the File.x10 class, but I detect some strange
behavior which I think it's a bug. When I run this simple example in
different machines I'm getting different results. Here is the code:
import x10.io.File;
public class Main {
public static def main(args:Rail[String]):void{
val fp = new File(args(0));
for (file in fp.list()){
Console.OUT.println(file);
}
}
}
I compile the code with the c++ backend (x10c++ Main.x10). When I run this
program in my machine passing as argument a basic directory with seven
empty files (file0, file1, ... file6) I'm getting this output:
$ ./main tmp
/home/danny/tmp/files/tmp/file2
/home/danny/tmp/files/tmp/file0
/home/danny/tmp/files/tmp/file1
/home/danny/tmp/files/tmp/.
/home/danny/tmp/files/tmp/file3
/home/danny/tmp/files/tmp/..
/home/danny/tmp/files/tmp/file5
As you can see, there are some missing files and the list also include the
'.' and '..' entries. Also I test in different machines and It seems that
this behavior only is presented for some casesSo I search for the list
implementation in the x10 sources, File__NativeFile.cc:
File__NativeFile::list() {
char sep = (char) (File::FMGL(SEPARATOR__get)().v);
DIR* dir;
struct dirent* de;
if((dir = ::opendir(path->c_str())) == NULL)
return NULL;
long i;
for(i = 0L; (de = ::readdir(dir)) != NULL; i++) ;
::rewinddir(dir);
::readdir(dir); // skip "." //Here is the problem
::readdir(dir); // skip ".."
Rail<String*>* rail = Rail<String*>::_make((x10_long)(i - 2L));
String* absPath = getAbsolutePath();
for(i = 0L; (de = ::readdir(dir)) != NULL; i++) {
char* tmp = (char*)::malloc(sizeof(char) *
((int)absPath->length() + 1 + ::strlen(de->d_name) + 1));
::sprintf(tmp, "%s%c%s", absPath->c_str(), sep, de->d_name);
rail->__set((x10_long)i, String::Steal(tmp));
}
::closedir(dir);
return rail;
}
I suppose that for some file systems the readdir() function doesn't return
the entries "." and ".." as the first two entries, so the lines to skip
these entries actually are skipping valid files. I changed a little bit
this function and It works:
File__NativeFile::list() {
char sep = (char) (File::FMGL(SEPARATOR__get)().v);
DIR* dir;
struct dirent* de;
if((dir = ::opendir(path->c_str())) == NULL)
return NULL;
long i;
for(i = 0L; (de = ::readdir(dir)) != NULL; i++) ;
::rewinddir(dir);
Rail<String*>* rail = Rail<String*>::_make((x10_long)(i - 2L));
String* absPath = getAbsolutePath();
for(i = 0L; (de = ::readdir(dir)) != NULL;){
if ( !strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") )
continue;
char* tmp = (char*)::malloc(sizeof(char) *
((int)absPath->length() + 1 + ::strlen(de->d_name) + 1));
::sprintf(tmp, "%s%c%s", absPath->c_str(), sep, de->d_name);
rail->__set((x10_long)i, String::Steal(tmp));
i++;
}
::closedir(dir);
return rail;
}
I test the same program with the java backend and there is no bug there,
but It's not standardized. The native backend returns the absolute path
while the managed backed simply returns the name of the file.
I hope you could include some changes in this package for the following X10
version.
Thank you!
Danny MĂșnera
------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
X10-users mailing list
X10-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/x10-users