initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
@ -0,0 +1,132 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UnityEditor.Build.Pipeline.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Since C# only has GZipStream until .NET 4.0, we are forced to implement our own packing system
|
||||
/// for artifact files. We compact all artifacts into a single GZip Stream with the header before
|
||||
/// the file name and contents. The header contains the file name length and file length (in bytes).
|
||||
/// </summary>
|
||||
public class FileCompressor
|
||||
{
|
||||
/// <summary>
|
||||
/// Compresses all artifacts located at a specified directory.
|
||||
/// </summary>
|
||||
/// <param name="directoryPath">The directory containing the artifacts.</param>
|
||||
/// <param name="archiveFilePath">The file path at which the archive will be created.</param>
|
||||
/// <returns>Returns true if the directory was found and compressed. Returns false otherwise.</returns>
|
||||
public static bool Compress(string directoryPath, string archiveFilePath)
|
||||
{
|
||||
if (!directoryPath.EndsWith("/") && !directoryPath.EndsWith("\\"))
|
||||
directoryPath += Path.DirectorySeparatorChar.ToString();
|
||||
|
||||
var directory = new DirectoryInfo(directoryPath);
|
||||
if (!directory.Exists)
|
||||
return false;
|
||||
|
||||
var files = directory.GetFiles("*", SearchOption.AllDirectories);
|
||||
files = files.Where(x => (File.GetAttributes(x.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden && x.Extension != ".sbpGz").ToArray();
|
||||
if (files.Length == 0)
|
||||
return false;
|
||||
|
||||
using (var archiveStream = new FileStream(archiveFilePath, FileMode.OpenOrCreate, FileAccess.Write))
|
||||
{
|
||||
using (var gZipStream = new GZipStream(archiveStream, CompressionMode.Compress))
|
||||
{
|
||||
foreach (var file in files)
|
||||
{
|
||||
var relativePath = file.FullName.Substring(directory.FullName.Length);
|
||||
relativePath = relativePath.Replace("\\", "/");
|
||||
|
||||
using (var fileStream = file.OpenRead())
|
||||
{
|
||||
byte[] filePathBytes = Encoding.ASCII.GetBytes(relativePath);
|
||||
|
||||
// Write chunk header
|
||||
gZipStream.Write(BitConverter.GetBytes(filePathBytes.Length), 0, sizeof(int));
|
||||
gZipStream.Write(BitConverter.GetBytes(fileStream.Length), 0, sizeof(long));
|
||||
|
||||
// Write chunk body
|
||||
// Write file path
|
||||
gZipStream.Write(filePathBytes, 0, filePathBytes.Length);
|
||||
|
||||
// Write file contents
|
||||
byte[] readBuffer = new byte[4096];
|
||||
int readSize = readBuffer.Length;
|
||||
while (readSize == readBuffer.Length)
|
||||
{
|
||||
readSize = fileStream.Read(readBuffer, 0, readBuffer.Length);
|
||||
gZipStream.Write(readBuffer, 0, readSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extracts all artifacts compressed in an archive.
|
||||
/// </summary>
|
||||
/// <param name="archiveFilePath">The archive to decompress.</param>
|
||||
/// <param name="directoryPath">The path where the extracted artifacts will be stored.</param>
|
||||
/// <returns>Returns true if the archive was found and decompressed. Returns false otherwise.</returns>
|
||||
public static bool Decompress(string archiveFilePath, string directoryPath)
|
||||
{
|
||||
var archiveFile = new FileInfo(archiveFilePath);
|
||||
if (!archiveFile.Exists)
|
||||
return false;
|
||||
|
||||
var directory = new DirectoryInfo(directoryPath);
|
||||
if (!directory.Exists)
|
||||
directory.Create();
|
||||
|
||||
using (var archiveStream = archiveFile.OpenRead())
|
||||
{
|
||||
using (var gZipStream = new GZipStream(archiveStream, CompressionMode.Decompress))
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// Read chunk header
|
||||
byte[] header = new byte[sizeof(int) + sizeof(long)];
|
||||
int readSize = gZipStream.Read(header, 0, header.Length);
|
||||
if (readSize != header.Length)
|
||||
break;
|
||||
|
||||
int filePathLength = BitConverter.ToInt32(header, 0);
|
||||
long fileLenth = BitConverter.ToInt64(header, sizeof(int));
|
||||
|
||||
// Read chunk body
|
||||
// Read file path
|
||||
byte[] filePathBytes = new byte[filePathLength];
|
||||
gZipStream.Read(filePathBytes, 0, filePathLength);
|
||||
string filePath = Encoding.ASCII.GetString(filePathBytes);
|
||||
|
||||
var pathSeperator = filePath.LastIndexOf("/");
|
||||
if (pathSeperator > -1)
|
||||
Directory.CreateDirectory(string.Format("{0}/{1}", directoryPath, filePath.Substring(0, pathSeperator)));
|
||||
|
||||
// Read file contents
|
||||
using (var fileStream = new FileStream(directoryPath + "/" + filePath, FileMode.OpenOrCreate, FileAccess.Write))
|
||||
{
|
||||
byte[] readBuffer = new byte[4096];
|
||||
long readRemaining = fileLenth;
|
||||
while (readRemaining > 0)
|
||||
{
|
||||
readSize = readBuffer.Length < readRemaining ? readBuffer.Length : (int)readRemaining;
|
||||
gZipStream.Read(readBuffer, 0, readSize);
|
||||
fileStream.Write(readBuffer, 0, readSize);
|
||||
readRemaining -= readSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue