/// <summary> /// adds a list of files to an archive. /// </summary> /// <param name="data"></param> /// <param name="destStream"></param> /// <param name="updIndex"></param> public static void AddData(List <ArchiveFile> data, Stream destStream, IndexHandler updIndex) { if (!destStream.CanWrite) { throw new ArgumentException("Cannot Write to Stream"); } if (!destStream.CanSeek) { throw new ArgumentException("Cannot Seek!"); } // enumerate the archive files: generate the index and the data. foreach (var file in data) { // serialize and compress the archive file byte[] serialData = file.ToByteArray(); // generate a new index: RawIndex idx = new RawIndex() { N = file.ToString(), L = serialData.Length }; AddRawData(destStream, idx, serialData, updIndex); } }
/// <summary> /// creates an archive with the given array of files, and returns the index handler. /// </summary> /// <param name="fileName"></param> /// <param name="data"></param> /// <returns></returns> public static IndexHandler CreateArchiveFile(String fileName, List <ArchiveFile> data) { IndexHandler handler = new IndexHandler(); using (FileStream fs = File.Create(fileName)) { AddData(data, fs, handler); } return(handler); }
/// <summary> /// opens an existing streaming archive file and reads in the indexes. /// if the file doesn't exist, or is zero length, prepares to write to the file. /// </summary> /// <param name="fileName"></param> public StreamingArchiveFile(String fileName) { if (File.Exists(fileName)) OpenArchive(fileName); else { // just be ready to add files: _fileName = fileName; _index = new IndexHandler(); } }
/// <summary> /// opens an existing streaming archive file and reads in the indexes. /// if the file doesn't exist, or is zero length, prepares to write to the file. /// </summary> /// <param name="fileName"></param> public StreamingArchiveFile(String fileName) { if (File.Exists(fileName)) { OpenArchive(fileName); } else { // just be ready to add files: _fileName = fileName; _index = new IndexHandler(); } }
/// <summary> /// creates a new streaming archive file with the given list of files. /// </summary> /// <param name="fileName"></param> /// <param name="fileData"></param> public StreamingArchiveFile(String fileName, List<ArchiveFile> fileData) { // record the archive file name _fileName = fileName; // create a new index handler: _index = new IndexHandler(); // write the file data to the stream using (Stream s = GetStream()) { AddData(fileData, s, _index); } }
/// <summary> /// creates a new streaming archive file with the given list of files. /// </summary> /// <param name="fileName"></param> /// <param name="fileData"></param> public StreamingArchiveFile(String fileName, List <ArchiveFile> fileData) { // record the archive file name _fileName = fileName; // create a new index handler: _index = new IndexHandler(); // write the file data to the stream using (Stream s = GetStream()) { AddData(fileData, s, _index); } }
/// <summary> /// open an existing streaming archive. /// </summary> /// <param name="fileName"></param> public void OpenArchive(String fileName) { // record the filename: _fileName = fileName; // create a new index handler: _index = new IndexHandler(); // read the index data: using (FileStream fs = File.OpenRead(fileName)) { // read all the indexes from the filestream _index.ReadIndexes(fs); } }
/// <summary> /// remove a list of files from the archive by the archive file index. /// this works by duplicating the archive file into a temp location, skipping the files due to be deleted /// and then copying the duplicate back over the original. /// not the most inspired solution but better than nothing. /// </summary> /// <param name="filesToRemove"></param> public void RemoveFiles(List <ArchiveFileIndex> filesToRemove) { // create a temporary file: String tempFileName = Path.GetTempFileName(); // create a temporary archive: StreamingArchiveFile tempArc = new StreamingArchiveFile(tempFileName); // extract each file from this archive, add it to the other archive, // except the files to be deleted. using (Stream input = GetStream()) { using (Stream output = tempArc.GetStream()) { // enumerate the indexes: foreach (ArchiveFileIndex idx in _index.ArchiveIndex) { if (!filesToRemove.Contains(idx)) { // process this... read in the raw data block: input.Seek(idx.FileStartIndex, SeekOrigin.Begin); // read the compressed file data: byte[] data = IndexHandler.ReadBuffer(input, idx.FileLength); // now generate the raw index: RawIndex rawIndex = new RawIndex() { N = idx.FileName, L = idx.FileLength }; // add to the destination: AddRawData(output, rawIndex, data, tempArc._index); } } } } // now copy the temp file back over the archive: File.Delete(_fileName); File.Move(tempFileName, _fileName); // now re-read the indexes: OpenArchive(_fileName); }
/// <summary> /// writes the index data and the raw file blocks to the destination stream. /// </summary> /// <param name="destStream"></param> /// <param name="idx"></param> /// <param name="dataArray"></param> /// <param name="updIndex"></param> public static void AddRawData(Stream destStream, RawIndex idx, byte[] dataArray, IndexHandler updIndex) { // serialize and compress the index data: byte[] indexData = RawIndex.ToByteArray(idx); // generate the header bytes: byte[] header = BitConverter.GetBytes((ushort)indexData.Length); // move to the end of the stream: destStream.Position = destStream.Length; // write the header data: destStream.Write(header, 0, header.Length); // write the index data: destStream.Write(indexData, 0, indexData.Length); // add the index record to the handler: updIndex.ArchiveIndex.Add(new ArchiveFileIndex() { FileLength = idx.L, FileName = idx.N, FileStartIndex = destStream.Position }); // write the data to the stream destStream.Write(dataArray, 0, dataArray.Length); }
/// <summary> /// adds a list of files to an archive. /// </summary> /// <param name="data"></param> /// <param name="destStream"></param> /// <param name="updIndex"></param> public static void AddData(List<ArchiveFile> data, Stream destStream, IndexHandler updIndex) { if (!destStream.CanWrite) throw new ArgumentException("Cannot Write to Stream"); if (!destStream.CanSeek) throw new ArgumentException("Cannot Seek!"); // enumerate the archive files: generate the index and the data. foreach (var file in data) { // serialize and compress the archive file byte[] serialData = file.ToByteArray(); // generate a new index: RawIndex idx = new RawIndex() { N = file.ToString(), L = serialData.Length }; AddRawData(destStream, idx, serialData, updIndex); } }
/// <summary> /// creates an archive with the given array of files, and returns the index handler. /// </summary> /// <param name="fileName"></param> /// <param name="data"></param> /// <returns></returns> public static IndexHandler CreateArchiveFile(String fileName, List<ArchiveFile> data) { IndexHandler handler = new IndexHandler(); using (FileStream fs = File.Create(fileName)) { AddData(data, fs, handler); } return handler; }
/// <summary> /// open an existing streaming archive. /// </summary> /// <param name="fileName"></param> public void OpenArchive(String fileName) { // record the filename: _fileName = fileName; // create a new index handler: _index = new IndexHandler(); // read the index data: using (FileStream fs = File.OpenRead(fileName)) { // read all the indexes from the filestream _index.ReadIndexes(fs); } }
/// <summary> /// extract this file from the specified stream. /// </summary> /// <param name="source"></param> /// <returns></returns> public ArchiveFile ExtractFile(Stream source) { return(IndexHandler.ExtractArchive(source, this)); }
/// <summary> /// writes the index data and the raw file blocks to the destination stream. /// </summary> /// <param name="destStream"></param> /// <param name="idx"></param> /// <param name="dataArray"></param> /// <param name="updIndex"></param> public static void AddRawData(Stream destStream, RawIndex idx, byte[] dataArray, IndexHandler updIndex) { // serialize and compress the index data: byte[] indexData = RawIndex.ToByteArray(idx); // generate the header bytes: byte[] header = BitConverter.GetBytes((ushort)indexData.Length); // move to the end of the stream: destStream.Position = destStream.Length; // write the header data: destStream.Write(header, 0, header.Length); // write the index data: destStream.Write(indexData, 0, indexData.Length); // add the index record to the handler: updIndex.ArchiveIndex.Add(new ArchiveFileIndex() { FileLength = idx.L, FileName = idx.N, FileStartIndex = destStream.Position }); // write the data to the stream destStream.Write(dataArray, 0, dataArray.Length); }