2015-04-04 15:22:20 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
namespace xServer.Core.Helper
|
|
|
|
|
{
|
|
|
|
|
public class FileSplit
|
|
|
|
|
{
|
|
|
|
|
private int _maxBlocks;
|
2015-06-07 14:28:33 +00:00
|
|
|
|
private readonly object _fileStreamLock = new object();
|
2015-07-10 10:41:48 +00:00
|
|
|
|
private const int MAX_BLOCK_SIZE = 65535;
|
2015-04-04 15:22:20 +00:00
|
|
|
|
public string Path { get; private set; }
|
|
|
|
|
public string LastError { get; private set; }
|
|
|
|
|
|
|
|
|
|
public int MaxBlocks
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (this._maxBlocks > 0 || this._maxBlocks == -1)
|
|
|
|
|
return this._maxBlocks;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
FileInfo fInfo = new FileInfo(this.Path);
|
|
|
|
|
|
|
|
|
|
if (!fInfo.Exists)
|
|
|
|
|
throw new FileNotFoundException();
|
|
|
|
|
|
2015-06-05 21:07:37 +00:00
|
|
|
|
this._maxBlocks = (int)Math.Ceiling(fInfo.Length / (double)MAX_BLOCK_SIZE);
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
|
|
|
|
catch (UnauthorizedAccessException)
|
|
|
|
|
{
|
|
|
|
|
this._maxBlocks = -1;
|
|
|
|
|
this.LastError = "Access denied";
|
|
|
|
|
}
|
2015-05-21 16:12:02 +00:00
|
|
|
|
catch (IOException ex)
|
2015-04-04 15:22:20 +00:00
|
|
|
|
{
|
|
|
|
|
this._maxBlocks = -1;
|
2015-05-21 16:12:02 +00:00
|
|
|
|
|
|
|
|
|
if (ex is FileNotFoundException)
|
|
|
|
|
this.LastError = "File not found";
|
|
|
|
|
if (ex is PathTooLongException)
|
|
|
|
|
this.LastError = "Path is too long";
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
2015-04-07 16:46:14 +00:00
|
|
|
|
|
2015-04-04 15:22:20 +00:00
|
|
|
|
return this._maxBlocks;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public FileSplit(string path)
|
|
|
|
|
{
|
|
|
|
|
this.Path = path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int GetSize(long length)
|
|
|
|
|
{
|
2015-06-05 21:07:37 +00:00
|
|
|
|
return (length < MAX_BLOCK_SIZE) ? (int) length : MAX_BLOCK_SIZE;
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool ReadBlock(int blockNumber, out byte[] readBytes)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2015-04-07 16:46:14 +00:00
|
|
|
|
if (blockNumber > this.MaxBlocks)
|
|
|
|
|
throw new ArgumentOutOfRangeException();
|
2015-04-04 15:22:20 +00:00
|
|
|
|
|
2015-06-07 14:28:33 +00:00
|
|
|
|
lock (_fileStreamLock)
|
2015-04-04 15:22:20 +00:00
|
|
|
|
{
|
2015-06-07 14:28:33 +00:00
|
|
|
|
using (FileStream fStream = File.OpenRead(this.Path))
|
2015-04-04 15:22:20 +00:00
|
|
|
|
{
|
2015-06-07 14:28:33 +00:00
|
|
|
|
if (blockNumber == 0)
|
|
|
|
|
{
|
|
|
|
|
fStream.Seek(0, SeekOrigin.Begin);
|
2015-07-24 13:46:11 +00:00
|
|
|
|
var length = fStream.Length - fStream.Position;
|
|
|
|
|
if (length < 0)
|
|
|
|
|
throw new IOException("negative length");
|
|
|
|
|
readBytes = new byte[this.GetSize(length)];
|
2015-06-07 14:28:33 +00:00
|
|
|
|
fStream.Read(readBytes, 0, readBytes.Length);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fStream.Seek(blockNumber*MAX_BLOCK_SIZE, SeekOrigin.Begin);
|
2015-07-24 13:46:11 +00:00
|
|
|
|
var length = fStream.Length - fStream.Position;
|
|
|
|
|
if (length < 0)
|
|
|
|
|
throw new IOException("negative length");
|
|
|
|
|
readBytes = new byte[this.GetSize(length)];
|
2015-06-07 14:28:33 +00:00
|
|
|
|
fStream.Read(readBytes, 0, readBytes.Length);
|
|
|
|
|
}
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentOutOfRangeException)
|
|
|
|
|
{
|
|
|
|
|
readBytes = new byte[0];
|
|
|
|
|
this.LastError = "BlockNumber bigger than MaxBlocks";
|
|
|
|
|
}
|
|
|
|
|
catch (UnauthorizedAccessException)
|
|
|
|
|
{
|
|
|
|
|
readBytes = new byte[0];
|
|
|
|
|
this.LastError = "Access denied";
|
|
|
|
|
}
|
2015-05-21 16:12:02 +00:00
|
|
|
|
catch (IOException ex)
|
2015-04-04 15:22:20 +00:00
|
|
|
|
{
|
|
|
|
|
readBytes = new byte[0];
|
2015-05-21 16:12:02 +00:00
|
|
|
|
|
|
|
|
|
if (ex is FileNotFoundException)
|
|
|
|
|
this.LastError = "File not found";
|
|
|
|
|
else if (ex is DirectoryNotFoundException)
|
|
|
|
|
this.LastError = "Directory not found";
|
|
|
|
|
else if (ex is PathTooLongException)
|
|
|
|
|
this.LastError = "Path is too long";
|
|
|
|
|
else
|
|
|
|
|
this.LastError = "Unable to read from File Stream";
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
2015-04-07 16:46:14 +00:00
|
|
|
|
|
|
|
|
|
return false;
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool AppendBlock(byte[] block, int blockNumber)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!File.Exists(this.Path) && blockNumber > 0)
|
|
|
|
|
throw new FileNotFoundException(); // previous file got deleted somehow, error
|
|
|
|
|
|
2015-06-07 14:28:33 +00:00
|
|
|
|
lock (_fileStreamLock)
|
2015-04-04 15:22:20 +00:00
|
|
|
|
{
|
2015-06-07 14:28:33 +00:00
|
|
|
|
if (blockNumber == 0)
|
2015-04-04 15:22:20 +00:00
|
|
|
|
{
|
2015-06-07 14:28:33 +00:00
|
|
|
|
using (FileStream fStream = File.Open(this.Path, FileMode.Create, FileAccess.Write))
|
|
|
|
|
{
|
|
|
|
|
fStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
fStream.Write(block, 0, block.Length);
|
|
|
|
|
}
|
2015-04-04 15:22:20 +00:00
|
|
|
|
|
2015-06-07 14:28:33 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2015-04-04 15:22:20 +00:00
|
|
|
|
|
2015-06-07 14:28:33 +00:00
|
|
|
|
using (FileStream fStream = File.Open(this.Path, FileMode.Append, FileAccess.Write))
|
|
|
|
|
{
|
|
|
|
|
fStream.Seek(blockNumber*MAX_BLOCK_SIZE, SeekOrigin.Begin);
|
|
|
|
|
fStream.Write(block, 0, block.Length);
|
|
|
|
|
}
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (UnauthorizedAccessException)
|
|
|
|
|
{
|
|
|
|
|
this.LastError = "Access denied";
|
|
|
|
|
}
|
2015-05-21 16:12:02 +00:00
|
|
|
|
catch (IOException ex)
|
2015-04-04 15:22:20 +00:00
|
|
|
|
{
|
2015-05-21 16:12:02 +00:00
|
|
|
|
if (ex is FileNotFoundException)
|
|
|
|
|
this.LastError = "File not found";
|
|
|
|
|
else if (ex is DirectoryNotFoundException)
|
|
|
|
|
this.LastError = "Directory not found";
|
|
|
|
|
else if (ex is PathTooLongException)
|
|
|
|
|
this.LastError = "Path is too long";
|
|
|
|
|
else
|
|
|
|
|
this.LastError = "Unable to write to File Stream";
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
2015-04-07 16:46:14 +00:00
|
|
|
|
|
|
|
|
|
return false;
|
2015-04-04 15:22:20 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2015-04-21 18:27:52 +00:00
|
|
|
|
}
|