port from perforce
This commit is contained in:
120
aiwaz/Aiwaz.Common/FileSystem.cs
Normal file
120
aiwaz/Aiwaz.Common/FileSystem.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Ionic.Zip;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace Aiwaz.Common
|
||||
{
|
||||
public class FileSystem : IDisposable
|
||||
{
|
||||
private Dictionary<string, Action<Stream>> attachedFiles = new Dictionary<string, Action<Stream>>();
|
||||
private ZipFile zipFile;
|
||||
private FileSystemWatcher watcher;
|
||||
private string directory;
|
||||
public FileSystem()
|
||||
{
|
||||
directory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
|
||||
this.watcher = new FileSystemWatcher(directory);
|
||||
this.watcher.NotifyFilter = NotifyFilters.LastWrite;
|
||||
this.watcher.IncludeSubdirectories = true;
|
||||
this.watcher.Changed += watcher_Changed;
|
||||
this.watcher.EnableRaisingEvents = true;
|
||||
if (File.Exists(Path.Combine(directory, "data.pak")))
|
||||
{
|
||||
zipFile = ZipFile.Read(Path.Combine(directory, "data.pak"));
|
||||
}
|
||||
}
|
||||
|
||||
void watcher_Changed(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
foreach (var entry in attachedFiles)
|
||||
{
|
||||
if (e.FullPath == entry.Key)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stream = new FileStream(e.FullPath, FileMode.Open);
|
||||
entry.Value(stream);
|
||||
break;
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~FileSystem()
|
||||
{
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
public void Attach(string argFileName, Action<Stream> onLoaded)
|
||||
{
|
||||
if (File.Exists(Path.Combine(directory, argFileName)))
|
||||
{
|
||||
Stream fileStream = new FileStream(Path.Combine(directory, argFileName), FileMode.Open);
|
||||
if (fileStream != null && onLoaded != null)
|
||||
{
|
||||
var fullPath = Path.Combine(directory, argFileName).Replace('/', '\\');
|
||||
attachedFiles[fullPath] = onLoaded;
|
||||
onLoaded(fileStream);
|
||||
}
|
||||
}
|
||||
else if (zipFile != null)
|
||||
{
|
||||
var file = zipFile[argFileName];
|
||||
if (file != null)
|
||||
{
|
||||
Stream outputStream = new MemoryStream();
|
||||
file.Extract(outputStream);
|
||||
if (onLoaded != null)
|
||||
onLoaded(outputStream);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FileNotFoundException(argFileName);
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (zipFile != null)
|
||||
{
|
||||
zipFile.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public static class BinaryReaderExtensions
|
||||
{
|
||||
public static string ReadNullTerminatedString(this BinaryReader reader)
|
||||
{
|
||||
string result = string.Empty;
|
||||
char readChar = '\0';
|
||||
do
|
||||
{
|
||||
readChar = reader.ReadChar();
|
||||
if (readChar != '\0')
|
||||
result += readChar;
|
||||
}
|
||||
while (readChar != '\0');
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user