hadoop 文件系统牺牲了一些POSIX要求,即写入的内容不能立即可见。
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class CoheModel {
public static void main(String[] args) throws IOException {
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(conf);
try {
OutputStream out=fs.create(new Path(args[0]));
out.write("contend".getBytes("UTF-8"));
out.flush();
assertThat(fs.getFileStatus(new Path(args[0])).getLen(), is(0l));
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里使用到了两个额外的包,junit禾hamcrest,运行hadoop命令之前要把hamcrest包放到hadoop根目录lib目录下,lib本身带有junit4.5的包,所以在编写这个程序之前的eclipse最好也是使用这个版本的junit包。因为assertThat和is都是静态的方法,所以在导入包的时使用了static,运行结果没有出现AssertException,说明这时的reader无法看见正在写入的块。
在out.flush 之后加上out.sync,或者out.close可以实现数据的同步。
做以下尝试:
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class CoheModel {
public static void main(String[] args) throws IOException {
Configuration conf=new Configuration();
FileSystem fs=FileSystem.get(conf);
try {
FSDataOutputStream out=fs.create(new Path(args[0]));
out.write("contend".getBytes("UTF-8"));
out.flush();
out.sync();
assertThat(fs.getFileStatus(new Path(args[0])).getLen(), is(7l));
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
出现了断言异常:
Exception in thread "main" java.lang.AssertionError:
Expected: is <7L>
got: <0L>
这是内存和数据节点没有同步的结果,把out.sync()换成out.close()能得到正确的结果,非常奇怪,有明白的朋友欢迎留言给我~