public static bool CompareDirectories(string dirA, string dirB) { bool difference = false; Console.WriteLine("Comparing directories {0}, {1}", dirA, dirB); string[] filesA = Directory.GetFiles(dirA); string[] filesB = Directory.GetFiles(dirB); for (int iA = 0; iA < filesA.Length; iA++) { filesA[iA] = Path.GetFileName(filesA[iA]); } for (int iB = 0; iB < filesB.Length; iB++) { filesB[iB] = Path.GetFileName(filesB[iB]); } Array.Sort(filesA); Array.Sort(filesB); for (int iA = 0, iB = 0; iA < filesA.Length || iB < filesB.Length;) { int comp; if (iA == filesA.Length) { comp = 1; } else if (iB == filesB.Length) { comp = -1; } else { comp = String.Compare(filesA[iA], filesB[iB]); } if (comp < 0) { Console.WriteLine("< " + filesA[iA]); difference = true; iA++; } else if (comp > 0) { Console.WriteLine("> " + filesB[iB]); difference = true; iB++; } else { string fileA = Path.Combine(dirA, filesA[iA]); string fileB = Path.Combine(dirB, filesB[iB]); byte[] hashA; byte[] hashB; lock (CompressionTestUtil.md5) { using (Stream fileAStream = File.OpenRead(fileA)) { hashA = CompressionTestUtil.md5.ComputeHash(fileAStream); } using (Stream fileBStream = File.OpenRead(fileB)) { hashB = CompressionTestUtil.md5.ComputeHash(fileBStream); } } for (int i = 0; i < hashA.Length; i++) { if (hashA[i] != hashB[i]) { Console.WriteLine("~ " + filesA[iA]); difference = true; break; } } iA++; iB++; } } string[] dirsA = Directory.GetDirectories(dirA); string[] dirsB = Directory.GetDirectories(dirB); for (int iA = 0; iA < dirsA.Length; iA++) { dirsA[iA] = Path.GetFileName(dirsA[iA]); } for (int iB = 0; iB < dirsB.Length; iB++) { dirsB[iB] = Path.GetFileName(dirsB[iB]); } Array.Sort(dirsA); Array.Sort(dirsB); for (int iA = 0, iB = 0; iA < dirsA.Length || iB < dirsB.Length;) { int comp; if (iA == dirsA.Length) { comp = 1; } else if (iB == dirsB.Length) { comp = -1; } else { comp = String.Compare(dirsA[iA], dirsB[iB]); } if (comp < 0) { Console.WriteLine("< {0}\\", dirsA[iA]); difference = true; iA++; } else if (comp > 0) { Console.WriteLine("> {1}\\", dirsB[iB]); difference = true; iB++; } else { string subDirA = Path.Combine(dirA, dirsA[iA]); string subDirB = Path.Combine(dirB, dirsB[iB]); if (!CompressionTestUtil.CompareDirectories(subDirA, subDirB)) { difference = true; } iA++; iB++; } } return(!difference); }
private IList <ArchiveFileInfo> RunZipPackUnpack(int fileCount, long fileSize, long maxArchiveSize, CompressionLevel compLevel) { Console.WriteLine("Creating zip archive with {0} files of size {1}", fileCount, fileSize); Console.WriteLine("MaxArchiveSize={0}, CompressionLevel={1}", maxArchiveSize, compLevel); string dirA = String.Format("{0}-{1}-A", fileCount, fileSize); if (Directory.Exists(dirA)) { Directory.Delete(dirA, true); } Directory.CreateDirectory(dirA); string dirB = String.Format("{0}-{1}-B", fileCount, fileSize); if (Directory.Exists(dirB)) { Directory.Delete(dirB, true); } Directory.CreateDirectory(dirB); string[] files = new string[fileCount]; for (int iFile = 0; iFile < fileCount; iFile++) { files[iFile] = TEST_FILENAME_PREFIX + iFile + ".txt"; CompressionTestUtil.GenerateRandomFile(Path.Combine(dirA, files[iFile]), iFile, fileSize); } string[] archiveNames = new string[1000]; for (int i = 0; i < archiveNames.Length; i++) { if (i < 100) { archiveNames[i] = String.Format( (i == 0 ? "{0}-{1}.zip" : "{0}-{1}.z{2:d02}"), fileCount, fileSize, i); } else { archiveNames[i] = String.Format( "{0}-{1}.{2:d03}", fileCount, fileSize, i); } } string progressTextFile = String.Format("progress_{0}-{1}.txt", fileCount, fileSize); CompressionTestUtil testUtil = new CompressionTestUtil(progressTextFile); IList <ArchiveFileInfo> fileInfo; using (ZipEngine zipEngine = new ZipEngine()) { zipEngine.CompressionLevel = compLevel; File.AppendAllText(progressTextFile, "\r\n\r\n====================================================\r\nCREATE\r\n\r\n"); zipEngine.Progress += testUtil.PrintArchiveProgress; OptionStreamContext streamContext = new OptionStreamContext(archiveNames, dirA, null); streamContext.OptionHandler = delegate(string optionName, object[] parameters) { // For testing purposes, force zip64 for only moderately large files. switch (optionName) { case "forceZip64": return(fileSize > UInt16.MaxValue); default: return(null); } }; zipEngine.Pack(streamContext, files, maxArchiveSize); string checkArchiveName = archiveNames[0]; if (File.Exists(archiveNames[1])) { checkArchiveName = archiveNames[1]; } using (Stream archiveStream = File.OpenRead(checkArchiveName)) { bool isArchive = zipEngine.IsArchive(archiveStream); Assert.IsTrue(isArchive, "Checking that created archive appears valid."); } IList <string> createdArchiveNames = new List <string>(archiveNames.Length); for (int i = 0; i < archiveNames.Length; i++) { if (File.Exists(archiveNames[i])) { createdArchiveNames.Add(archiveNames[i]); } else { break; } } Assert.AreNotEqual <int>(0, createdArchiveNames.Count); Console.WriteLine("Listing zip archive with {0} files of size {1}", fileCount, fileSize); File.AppendAllText(progressTextFile, "\r\n\r\nLIST\r\n\r\n"); fileInfo = zipEngine.GetFileInfo( new ArchiveFileStreamContext(createdArchiveNames, null, null), null); Assert.AreEqual <int>(fileCount, fileInfo.Count); Console.WriteLine("Extracting zip archive with {0} files of size {1}", fileCount, fileSize); File.AppendAllText(progressTextFile, "\r\n\r\nEXTRACT\r\n\r\n"); zipEngine.Unpack(new ArchiveFileStreamContext(createdArchiveNames, dirB, null), null); } bool directoryMatch = CompressionTestUtil.CompareDirectories(dirA, dirB); Assert.IsTrue(directoryMatch, "Testing whether zip output directory matches input directory."); return(fileInfo); }