public override void Close() { if(!finished) { Finish(); } this.outStream.Close(); currentEntry = null; }
public static void WriteArFile(string output, params string[] inputs) { using (var stream = new FileOutputStream(output)) using (var ar = new ArArchiveOutputStream(stream)) { foreach (var file in inputs) { var info = new FileInfo(file); var name = Path.GetFileName(file); var entry = new ArArchiveEntry(name, info.Length); ar.putArchiveEntry(entry); using (var input = new FileInputStream(file)) IOUtils.copy(input, ar); ar.closeArchiveEntry(); } } }
private long WriteEntryHeader(ArArchiveEntry pEntry) { long offset = 0; string longName = null; string n = pEntry.Name; if (n.Length > 16) { // BSD variant // Seems to be incorrect or not work on debian ar //longName = n; //n = "#1/" + n.Length; throw new IOException ("filename too long, > 16 chars: " + n); } offset += Write (n); offset = Fill (offset, 16, ' '); // TODO: Ojo tiempo .net //String m = "" + (pEntry.LastModified / 1000); String m = "1264026598"; if (m.Length > 12) { throw new IOException ("modified too long"); } offset += Write (m); offset = Fill (offset, 28, ' '); String u = "" + pEntry.UserId; if (u.Length > 6) { throw new IOException ("userid too long"); } offset += Write (u); offset = Fill (offset, 34, ' '); String g = "" + pEntry.GroupId; if (g.Length > 6) { throw new IOException ("groupid too long"); } offset += Write (g); offset = Fill (offset, 40, ' '); //String fm = "" + Integer.toString(pEntry.Mode, 8); String fm = "0100644"; if (fm.Length > 8) { throw new IOException ("filemode too long"); } offset += Write (fm); offset = Fill (offset, 48, ' '); String s = "" + pEntry.Size; if (s.Length > 10) { throw new IOException ("size too long"); } offset += Write (s); offset = Fill (offset, 58, ' '); offset += Write (ArArchiveEntry.TRAILER); if (longName != null) { offset += Write (longName); } return offset; }
public override void PutArchiveEntry(ArchiveEntry pEntry) { if (finished) { throw new IOException ("Stream has already been finished"); } ArArchiveEntry pArEntry = (ArArchiveEntry)pEntry; if (currentEntry == null) { // First entry WriteArchiveHeader (); } else { if (currentEntry.Size != entryOffset) { throw new IOException ("length does not match entry (" + currentEntry.Size + " != " + entryOffset); } if (haveUnclosedEntry) { CloseArchiveEntry (); } } currentEntry = pArEntry; WriteEntryHeader (pArEntry); entryOffset = 0; haveUnclosedEntry = true; }
public ArArchiveEntry GetNextArEntry() { // read to the end of current entry data if (currentEntry != null) { long iread = 0; do { iread = this.Read (buffer, 0, buffer.Length); } while (iread > 0); currentEntry = null; } if (this.Position == 0) { // First entry // File header byte[] expected = new System.Text.ASCIIEncoding ().GetBytes (ArArchiveEntry.HEADER); byte[] realized = new byte[expected.Length]; int read = inputStream.Read (realized, 0, expected.Length); this.Count (read); if (read != expected.Length) { throw new IOException ("failed to read header. Occured at byte: " + this.Position); } for (int i = 0; i < expected.Length; i++) { if (expected[i] != realized[i]) { throw new IOException ("invalid header " + new System.Text.ASCIIEncoding ().GetString (realized)); } } } if (this.Position % 2 != 0) { if (inputStream.ReadByte () < 0) { // hit eof return null; } this.Count (1); } byte[] header = new byte[60]; int rea = this.inputStream.Read (header, 0, header.Length); this.Count (rea); if (rea <= 0) { // Clean end of file; return null; } if (rea != header.Length) { throw new IOException ("invalid header"); } if (header[58] != 0x60 || header[59] != 0x0A) { throw new IOException ("invalid magic tail on header"); } string name = Utilidades.UtArrays.LeerTexto (header, 0, 16).Trim (); long size = long.Parse (Utilidades.UtArrays.LeerTexto (header, 48, 10).Trim ()); if (name.EndsWith ("/")) { name = name.Substring (0, name.Length - 1); } // TODO Leer todos los campos de la cabecera currentEntry = new ArArchiveEntry (name, size); // GNU AR if (currentEntry.Name.Equals ("/")) { ReadGNUFilenamesEntry (); return GetNextArEntry (); } else if (currentEntry.Name.StartsWith ("/") && gnuNames.Count > 0) { currentEntry.name = (string)gnuNames[currentEntry.Name.Substring(1)]; } // BSD AR if (currentEntry.Name.StartsWith ("#1/")) { string t = currentEntry.Name.Substring (3); int s = int.Parse (t); if (s > 2048) { throw new IOException ("Filename too long (bsd)"); } byte[] buffer2 = new byte[s]; int l = this.inputStream.Read (buffer2, 0, buffer2.Length); if (l != s) { throw new IOException ("Filename error (bsd)"); } currentEntry.name = Utilidades.UtArrays.LeerTexto (buffer2, 0); } dataStream = new SizeLimiterStream (this.inputStream, currentEntry.Size); return currentEntry; }