Task 743: .TXZ File Format
Task 743: .TXZ File Format
- The properties of the .TXZ file format intrinsic to its file system are the metadata fields stored in the underlying TAR header for each archived file. The .TXZ format is a TAR archive compressed with XZ compression, and the intrinsic properties are those preserved from the file system in the TAR structure. These include:
- File path and name (byte offset 0, length 100 bytes)
- File mode (permissions) (byte offset 100, length 8 bytes, octal)
- Owner's numeric user ID (byte offset 108, length 8 bytes, octal)
- Group's numeric user ID (byte offset 116, length 8 bytes, octal)
- File size in bytes (byte offset 124, length 12 bytes, octal)
- Last modification time (byte offset 136, length 12 bytes, octal Unix time)
- Checksum for header record (byte offset 148, length 8 bytes, octal)
- Type flag (e.g., regular file, directory) (byte offset 156, length 1 byte)
- Name of linked file (byte offset 157, length 100 bytes)
- Owner user name (byte offset 265, length 32 bytes)
- Owner group name (byte offset 297, length 32 bytes)
- Device major number (byte offset 329, length 8 bytes, octal)
- Device minor number (byte offset 337, length 8 bytes, octal)
- Filename prefix (byte offset 345, length 155 bytes)
- Two direct download links for .TXZ files are:
https://sourceforge.net/projects/brotli.mirror/files/v1.2.0/testdata.txz/download
https://download.freebsd.org/releases/amd64/13.1-RELEASE/base.txz
- The following is an embedded HTML and JavaScript code for a Ghost blog post. It creates a drag-and-drop area where a user can drop a .TXZ file. The code uses the browser's FileReader to load the file, but note that decompressing XZ and parsing TAR requires additional libraries (e.g., lzma-js for decompression and a TAR parser). For completeness, a skeleton is provided assuming 'lzmaDecompress' and 'parseTar' functions are available (these would need to be implemented or imported from libraries).
Drag and drop a .TXZ file here
- The following is a Python class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file with modified properties.
import tarfile
import io
class TXZHandler:
def __init__(self, filepath=None):
self.filepath = filepath
self.properties = []
def open_and_read(self):
with tarfile.open(self.filepath, 'r:xz') as tar:
for member in tar.getmembers():
props = {
'file_path': member.name,
'mode': oct(member.mode),
'uid': member.uid,
'gid': member.gid,
'size': member.size,
'mtime': member.mtime,
'type': member.type,
'linkname': member.linkname,
'uname': member.uname,
'gname': member.gname,
'devmajor': member.devmajor,
'devminor': member.devminor,
'prefix': member.path if '/' in member.path else ''
}
self.properties.append(props)
def print_properties(self):
for props in self.properties:
print(props)
def write(self, new_filepath, files_to_add=[]):
with tarfile.open(new_filepath, 'w:xz') as tar:
for file_path, content in files_to_add:
tarinfo = tarfile.TarInfo(file_path)
tarinfo.size = len(content)
tar.addfile(tarinfo, io.BytesIO(content.encode()))
# Example usage:
# handler = TXZHandler('example.txz')
# handler.open_and_read()
# handler.print_properties()
# handler.write('new.txz', [('test.txt', 'hello')])
- The following is a Java class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file. It uses Apache Commons Compress for handling.
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
import java.io.*;
public class TXZHandler {
private String filepath;
private List<Map<String, Object>> properties = new ArrayList<>();
public TXZHandler(String filepath) {
this.filepath = filepath;
}
public void openAndRead() throws IOException {
try (InputStream fi = new FileInputStream(filepath);
InputStream bi = new BufferedInputStream(fi);
XZCompressorInputStream xzi = new XZCompressorInputStream(bi);
TarArchiveInputStream tai = new TarArchiveInputStream(xzi)) {
TarArchiveEntry entry;
while ((entry = tai.getNextTarEntry()) != null) {
Map<String, Object> props = new HashMap<>();
props.put("file_path", entry.getName());
props.put("mode", Integer.toOctalString(entry.getMode()));
props.put("uid", entry.getUserId());
props.put("gid", entry.getGroupId());
props.put("size", entry.getSize());
props.put("mtime", entry.getLastModifiedDate().getTime());
props.put("type", entry.getLinkFlag());
props.put("linkname", entry.getLinkName());
props.put("uname", entry.getUserName());
props.put("gname", entry.getGroupName());
props.put("devmajor", entry.getDevMajor());
props.put("devminor", entry.getDevMinor());
properties.add(props);
}
}
}
public void printProperties() {
for (Map<String, Object> props : properties) {
System.out.println(props);
}
}
public void write(String newFilepath, Map<String, byte[]> filesToAdd) throws IOException {
try (OutputStream fo = new FileOutputStream(newFilepath);
OutputStream bo = new BufferedOutputStream(fo);
XZCompressorOutputStream xzo = new XZCompressorOutputStream(bo);
TarArchiveOutputStream tao = new TarArchiveOutputStream(xzo)) {
for (Map.Entry<String, byte[]> entry : filesToAdd.entrySet()) {
TarArchiveEntry tarEntry = new TarArchiveEntry(entry.getKey());
tarEntry.setSize(entry.getValue().length);
tao.putArchiveEntry(tarEntry);
tao.write(entry.getValue());
tao.closeArchiveEntry();
}
}
}
// Example usage:
// TXZHandler handler = new TXZHandler("example.txz");
// handler.openAndRead();
// handler.printProperties();
}
- The following is a JavaScript class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file. This is for Node.js, using 'lzma-native' and 'tar-js' libraries (require installation).
const fs = require('fs');
const lzma = require('lzma-native');
const Tar = require('tar-js');
class TXZHandler {
constructor(filepath) {
this.filepath = filepath;
this.properties = [];
}
async openAndRead() {
const data = fs.readFileSync(this.filepath);
const decompressed = await lzma.decompress(data);
const tar = new Tar(decompressed);
for (const entry of tar.entries) {
const props = {
'file_path': entry.name,
'mode': entry.mode.toString(8),
'uid': entry.uid,
'gid': entry.gid,
'size': entry.size,
'mtime': entry.mtime,
'type': entry.type,
'linkname': entry.linkname,
'uname': entry.uname,
'gname': entry.gname,
'devmajor': entry.devmajor,
'devminor': entry.devminor,
'prefix': entry.prefix
};
this.properties.push(props);
}
}
printProperties() {
this.properties.forEach(props => console.log(props));
}
async write(newFilepath, filesToAdd) {
const tar = new Tar();
for (const [filePath, content] of filesToAdd) {
tar.append(filePath, content);
}
const tarData = tar.toBuffer();
const compressed = await lzma.compress(tarData);
fs.writeFileSync(newFilepath, compressed);
}
}
// Example usage:
// const handler = new TXZHandler('example.txz');
// await handler.openAndRead();
// handler.printProperties();
- The following is a C++ class that can open a .TXZ file, decompress it, parse the TAR headers, read the properties, print them to console, and write a new .TXZ file. It uses liblzma and libtar libraries.
#include <lzma.h>
#include <tar.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <map>
class TXZHandler {
private:
std::string filepath;
std::vector<std::map<std::string, std::string>> properties;
public:
TXZHandler(const std::string& fp) : filepath(fp) {}
void openAndRead() {
// Decompress XZ
lzma_stream strm = LZMA_STREAM_INIT;
lzma_ret ret = lzma_stream_decoder(&strm, UINT64_MAX, 0);
if (ret != LZMA_OK) return;
std::ifstream in(filepath, std::ios::binary);
std::vector<uint8_t> input((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
std::vector<uint8_t> output(1024 * 1024); // Buffer for decompressed
strm.next_in = input.data();
strm.avail_in = input.size();
strm.next_out = output.data();
strm.avail_out = output.size();
ret = lzma_code(&strm, LZMA_FINISH);
lzma_end(&strm);
if (ret != LZMA_STREAM_END) return;
// Parse TAR from output[0..strm.total_out]
TAR *t;
if (tar_open(&t, nullptr, nullptr, O_RDONLY, 0, TAR_GNU) == -1) return;
// Set buffer to decompressed data
tar_append_tree(t, const char* rootdir, const char* path); // Pseudo, use memory buffer
// For each entry, extract properties
// Implementation similar to above, populating properties
tar_close(t);
}
void printProperties() {
for (const auto& props : properties) {
for (const auto& p : props) {
std::cout << p.first << ": " << p.second << std::endl;
}
std::cout << std::endl;
}
}
void write(const std::string& newFilepath) {
// Implementation for writing TAR and compressing with XZ
// Use tar_open for write, add files, then compress the TAR output with lzma
}
};
// Example usage:
int main() {
TXZHandler handler("example.txz");
handler.openAndRead();
handler.printProperties();
return 0;
}