Novell in HDFS和Hadoop: 我正在开发一个程序,应该获取特定目录的所有文件,我们可以找到几个任何类型的小文件。
获取每个文件并在压缩的SequenceFile中进行追加,其中键必须是文件的路径,并且值必须是得到的文件,现在我的代码是:
import java.net.*;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.io.compress.BZip2Codec;
public class Compact {
public static void main (String [] args) throws Exception{
try{
Configuration conf = new Configuration();
FileSystem fs =
FileSystem.get(new URI("hdfs://quickstart.cloudera:8020"),conf);
Path destino = new Path("/user/cloudera/data/testPractice.seq");//test args[1]
if ((fs.exists(destino))){
System.out.println("exist : " + destino);
return;
}
BZip2Codec codec=new BZip2Codec();
SequenceFile.Writer outSeq = SequenceFile.createWriter(conf
,SequenceFile.Writer.file(fs.makeQualified(destino))
,SequenceFile.Writer.compression(SequenceFile.CompressionType.BLOCK,codec)
,SequenceFile.Writer.keyClass(Text.class)
,SequenceFile.Writer.valueClass(FSDataInputStream.class));
FileStatus[] status = fs.globStatus(new Path("/user/cloudera/data/*.txt"));//args[0]
for (int i=0;i<status.length;i++){
FSDataInputStream in = fs.open(status[i].getPath());
outSeq.append(new org.apache.hadoop.io.Text(status[i].getPath().toString()), new FSDataInputStream(in));
fs.close();
}
outSeq.close();
System.out.println("End Program");
}catch(Exception e){
System.out.println(e.toString());
System.out.println("File not found");
}
}
}
但是在每次执行之后我都会收到这个例外:
java.io.IOException: Could not find a serializer for the Value class: 'org.apache.hadoop.fs.FSDataInputStream'. Please ensure that the configuration 'io.serializations' is properly configured, if you're usingcustom serialization.
找不到文件
我理解错误必须是我正在创建的文件类型以及我为添加到sequenceFile定义的对象类型,但我不知道应该添加哪个,有人可以帮助我吗?
提前致谢
答案 0 :(得分:0)
与其他任何InputStream一样,FSDataInputStream不是要序列化的。什么序列化字节流上的“迭代器”应该做什么?
您最想要做的是将文件的内容存储为值。例如,您可以将值类型从FsDataInputStream切换到BytesWritable,只需从FSDataInputStream中获取所有字节。为此目的使用Key / Value SequenceFile的一个缺点是每个文件的内容必须适合内存。对于小文件来说可能没什么问题,但你必须意识到这个问题。
我不确定你到底想要实现什么,但也许你可以通过Hadoop Archives之类的东西避免重新发明轮子?
答案 1 :(得分:0)
非常感谢你的评论,问题就像你说的序列化器,最后我使用了BytesWritable:
FileStatus[] status = fs.globStatus(new Path("/user/cloudera/data/*.txt"));//args[0]
for (int i=0;i<status.length;i++){
FSDataInputStream in = fs.open(status[i].getPath());
byte[] content = new byte [(int)fs.getFileStatus(status[i].getPath()).getLen()];
outSeq.append(new org.apache.hadoop.io.Text(status[i].getPath().toString()), new org.apache.hadoop.io.BytesWritable(in));
}
outSeq.close();
在hadoop生态系统中可能还有其他更好的解决方案,但这个问题是我正在开发的一个学位的练习,现在我们正在重新理解概念的轮子; - )。