背景说明
项目中,为了减少备份机房hdfs namenode内存压力,将采集文件压缩成tar,再传输至备份机房。在此期间,为了确保跨集群传输tar包的正确性,在生成tar文件时,需要生成crc32值。下面给出了java生成crc32值的代码。
具体代码实现
public interface IChunkSum extends Checksum
{
/**
* 获取校验值
* @return
*/
public String getStringValue();
}
public class Crc32ChunkSum implements IChunkSum
{
private CRC32 crc = new CRC32();
@Override
public void update(int b)
{
crc.update(b);
}
@Override
public void update(byte[] b, int off, int len)
{
crc.update(b, off, len);
}
@Override
public long getValue()
{
return crc.getValue();
}
@Override
public void reset()
{
crc.reset();
}
@Override
public String getStringValue()
{
return String.valueOf(getValue());
}
}
Crc32ChunkSum crc32ChunkSum = new Crc32ChunkSum();
try (TarArchiveOutputStream os = new TarArchiveOutputStream(new CheckedOutputStream(fs.create(new Path(fullTarName.toString())),crc32ChunkSum)))
{
InputStream is = null;
Path path = null;
for (FileInfo file : files)
{
path = new Path(file.getFullFilePath());
is = fs.open(new Path(file.getFullFilePath()));
TarArchiveEntry entry = new TarArchiveEntry(path.getName());
entry.setSize(file.getSize());
os.putArchiveEntry(entry);
IOUtils.copy(is, os);
os.closeArchiveEntry();
IOUtils.closeQuietly(is);
}
IOUtils.closeQuietly(os);
LOGGER.info("compress task run success,tar name is,{}",tarName);
Timestamp endDate = new Timestamp(System.currentTimeMillis());
ContextFactory.getContext().publishEvent(new CompressTaskEvent(tarName, dir, true, files, interfaceFileName,type,beginDate,endDate,crc32ChunkSum.getStringValue()));
}
压缩模块和下载模块都是采用上述方式计算出的值,因此,如果传输没有问题,起码两边计算出的CRC32值是一致的。
疑惑,待查
1、网上推荐一个linux计算CRC值的命令—cksum,但是与上述代码计算值不一样~(待后续研究)
2、另外,hdfs dfs -checksum 命令,也可以计算出一个值,该值与上述代码计算出来的也不一样。