#tar #tar-archive #read-write #read-stream #encoding

basic_tar

用于读取和写入经典旧式tar存档和流的构建块

2个版本

0.1.1 2019年8月5日
0.1.0 2019年8月5日

#680压缩

BSD-2-Clause OR MIT

23KB
316

docs.rs License BSD-2-Clause License MIT crates.io Download numbers Travis CI AppVeyor CI dependency status

basic_tar

欢迎来到 basic_tar 🎉

关于

此crate提供了一些读取和写入基本/经典旧式tar存档的功能,以及一些对io::Readio::Write的扩展,以便更容易地处理tar流。

注意:这并不是一个高级的通用(解)压缩工具,而是如果你想要在自己的应用中使用tar格式的话的一个构建块 - 对于高级解决方案,请查看 tar

如何读取流

要从存档流中读取tar记录,你需要读取

  1. 下一个记录的头部
  2. 有效载荷
  3. 填充字节,这些填充字节将有效载荷填充到块大小的倍数(512字节)

示例

use std::{ convert::TryFrom, error::Error, io::Read };
use basic_tar::{
	ReadExt, U64Ext, Header,
	raw::{ self, BLOCK_LEN }
};

/// Reads the next record from `stream`
fn read_next(mut stream: impl Read) -> Result<(Header, Vec<u8>), Box<dyn Error + 'static>> {
	// Read the header
	let mut header_raw = raw::header::raw();
	stream.read_exact(&mut header_raw)?;

	// Parse the header and get the payload lengths
	let header = Header::parse(header_raw)?;
	let payload_len = header.size;
	let payload_total_len = payload_len.ceil_to_multiple_of(BLOCK_LEN as u64);

	// Read the payload
	let mut payload = vec![0; usize::try_from(payload_len)?];
	stream.read_exact(&mut payload)?;

	// Drain the padding and return the record
	let padding_len = usize::try_from(payload_total_len - payload_len)?;
	stream.try_drain(padding_len, |_| {})?;
	Ok((header, payload))
}

如何写入流

要将tar记录写入存档流,你需要写入

  1. 你的头部
  2. 你的有效载荷
  3. 填充字节,将你的有效载荷填充到块大小的倍数(512字节)

示例

use std::{ convert::TryFrom, error::Error, io::Write };
use basic_tar::{ WriteExt, U64Ext, Header, raw::BLOCK_LEN };

/// Writes `header` and `payload` to `stream`
fn write_next(header: Header, payload: &[u8], mut stream: impl Write)
	-> Result<(), Box<dyn Error + 'static>>
{
	// Serialize the header and write it and the payload
	let header_raw = header.serialize()?;
	stream.write_all(&header_raw)?;
	stream.write_all(payload)?;

	// Write the padding
	let payload_len = payload.len() as u64;
	let padding_len = payload_len.ceil_to_multiple_of(BLOCK_LEN as u64) - payload_len;
	stream.try_fill(usize::try_from(padding_len)?, |_| {})?;

	Ok(())
}

无运行时依赖