/// <summary> /// Gets a stream to read a <see cref="JFile"/> contents /// </summary> /// <remarks> /// The stream can be a <see cref="JVirtualFileStream"/> if no /// filters are used or a <see cref="System.IO.MemoryStream"/> if they are /// </remarks> /// <param name="file">File to read the contents</param> /// <returns>A stream to read the file</returns> private Stream GetStream(JFile file) { JVirtualFileStream baseStream; if (file == null) return null; baseStream = new JVirtualFileStream(_storageFileStream, file.Offset, file.Length); return file.ApplyFiltersForRead(baseStream); }
/// <summary> /// Adds a file to a directory inside a path that starts in this /// directory /// </summary> /// <param name="path">Path to add the file</param> /// <param name="file">File to add</param> public void AddFile(String path, JFile file) { JDirectory directory; directory = GetDirectory(path); if (directory == null) throw new IOException("The path " + path + " is not correct in the JDirectory " + _name + "."); directory.AddFile(file); }
/// <summary> /// Adds a file to this directory /// </summary> /// <param name="file">File to add</param> public void AddFile(JFile file) { _files.Add(new JFileName(file.Name), file); file.Parent = this; }
/// <summary> /// Writes a <see cref="JFile"/> data into the storage file. /// </summary> /// <param name="file"><see cref="JFile"/> to write.</param> private void WriteFile(JFile file) { Stream inputStream; long start, end, totalBytesWriten; int bytesRead; byte[] bytes; // Get the offset position of the file file.Offset = writer.BaseStream.Position; // Check the file's location and get the stream to read it inputStream = null; if (file.FileInfo.Type == JFileType.Disk) inputStream = file.FileInfo.Info.Open(FileMode.Open, FileAccess.Read); if (file.FileInfo.Type == JFileType.Storage) inputStream = _oldStorage.GetFile(Path.GetDirectoryName(file.GetQualifiedName()), file.Name, false); if (inputStream == null) throw new ArgumentException("The JFileType of the file " + file.Name + " is not correct."); // Auxiliar buffer for reading bytes = new byte[4096]; // No filters, live is nice and lovely if (file.Filters.Count == 0) { // Calculate the real length as the file could have being compressed totalBytesWriten = 0; while ((bytesRead = inputStream.Read(bytes, 0, bytes.Length)) != 0) { writer.Write(bytes, 0, bytesRead); totalBytesWriten += bytesRead; } end = writer.BaseStream.Position; } else // The file has filters, apply them to write and prepare to have fun { // Get the start position start = writer.BaseStream.Position; // Close the writer (we are going to modify the stream) writer.Close(); // Reopen the file stream and apply the filters FileStream auxFile = new FileStream(_tempFile, FileMode.Append, FileAccess.Write); Stream auxStream = file.ApplyFiltersForWrite(auxFile); // Create the new writer and write the data BinaryWriter auxWriter = new BinaryWriter(auxStream); while ((bytesRead = inputStream.Read(bytes, 0, bytes.Length)) != 0) auxWriter.Write(bytes, 0, bytesRead); auxWriter.Flush(); // Get the end position and calculate the length end = auxFile.Position; totalBytesWriten = end - start; // Close the auxiliar writer and reopen the file without the filters auxWriter.Close(); writer = new BinaryWriter(new FileStream(_tempFile, FileMode.Open, FileAccess.ReadWrite)); } // Close the input file inputStream.Close(); // Write the file offset and length in the file header info writer.Seek((int) _fileOffsets[0], SeekOrigin.Begin); writer.Write(file.Offset); writer.Write(totalBytesWriten); // Remove the header offset of this file _fileOffsets.RemoveAt(0); // Seek to the end writer.Seek(0, SeekOrigin.End); }
/// <summary> /// Writes a <see cref="JFile"/> header into the storage file. /// </summary> /// <param name="file"><see cref="JFile"/> to write.</param> /// <param name="path">Path of the <see cref="JFile"/></param> private void WriteFileHeader(JFile file, string path) { int index; // Write the file header writer.Write(file.Name); writer.Write(path); // Mark the offset position for this file _fileOffsets.Add(writer.BaseStream.Position); writer.Write((long) -1); // The real offset has to be calculated later on writer.Write((long) -1); // The real length has to be calculated later on (it can change if the file has filters applied to it) // Write the filters data writer.Write(file.Filters.Count); for (int i = 0; i < file.Filters.Count; i++) { // Find the filter in the filters list index = -1; for (int j = 0; j < _newStorage.Filters.Count; j++) if (file.Filters[i] == _newStorage.Filters[j]) { index = j; break; } if (index == -1) throw new ApplicationException("The file " + file.Name + " has a filter called " + file.Filters[i].GetType().ToString() + " that doesn´t exist in the filter list of the storage file."); writer.Write(index); } }
/// <summary> /// Loads the files into the storage file. /// </summary> /// <param name="reader">Reader.</param> /// <param name="numberOfFiles">Number of files in the storage file.</param> private void LoadFiles(BinaryReader reader, int numberOfFiles) { String name, path; long offset, length; int numberOfFilters, filterIndex; JFile file; for (int i = 0; i < numberOfFiles; i++) { //Read the file fields name = reader.ReadString(); path = reader.ReadString(); offset = reader.ReadInt64(); length = reader.ReadInt64(); //Create the file and add it to the directory file = new JFile(name, offset, length); _newStorage.Root.AddFile(path, file); //Read the filters that affect this file numberOfFilters = reader.ReadInt32(); for (int j = 0; j < numberOfFilters; j++) { filterIndex = reader.ReadInt32(); file.Filters.Add(_newStorage.Filters[filterIndex]); } } }