using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace TextFileSplitter
{
class Program
{
static void Main(string[] args)
{
var exe = Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location);
if (args.Length < 4)
{
Console.WriteLine("Usage: {0} <InputFile> <SectionStartString> <SectionEndString> <OutputFolder>", exe);
return;
}
// Inputs
var inputFile = args[0].Trim();
var sectionStartString = args[1].Trim();
var sectionEndString = args[2].Trim();
var outputFolder = args[3].Trim();
var inputFileFilename = Path.GetFileNameWithoutExtension(inputFile);
var inputFilenameExtension = Path.GetExtension(inputFile);
// Quick and dirty validation
var validation = validateInput(inputFile, sectionStartString, sectionEndString, outputFolder);
if (validation.Any())
{
foreach (var validationError in validation)
Console.WriteLine("Error: " + validationError);
return;
}
// Go go go
using (FileStream fsInput = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bsInput = new BufferedStream(fsInput))
using (StreamReader srInput = new StreamReader(bsInput, Encoding.UTF8))
{
var outputting = false;
var outputFileCount = 0;
String outputFilename = string.Empty;
// Output streams
FileStream fsOutput = null;
BufferedStream bsOutput = null;
StreamWriter swOutput = null;
try
{
string line;
int lineCount = 0;
while ((line = srInput.ReadLine()) != null)
{
++lineCount;
if (++lineCount % 10 == 0)
Console.WriteLine("Processing line {0}..", lineCount);
var lineIsSectionStartString = line.Trim().Equals(sectionStartString, StringComparison.InvariantCultureIgnoreCase);
if (lineIsSectionStartString)
{
outputting = true;
// Initialise output streams
outputFilename = Path.Combine(outputFolder, string.Format("{0}-{1}{2}", inputFileFilename, ++outputFileCount, inputFilenameExtension));
fsOutput = File.Open(outputFilename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
bsOutput = new BufferedStream(fsOutput);
swOutput = new StreamWriter(bsOutput, Encoding.UTF8);
swOutput.AutoFlush = false;
Console.WriteLine("Outputting to {0}", outputFilename);
}
else if (outputting && line.Trim().Equals(sectionEndString, StringComparison.InvariantCultureIgnoreCase))
{
// Flush
swOutput.Flush();
bsOutput.Flush();
fsOutput.Flush();
Console.WriteLine("Closing {0}", outputFilename);
// Close output streams
outputting = false;
swOutput.Close();
bsOutput.Close();
fsOutput.Close();
}
if (outputting && !lineIsSectionStartString)
swOutput.WriteLine(line);
}
Console.WriteLine("Finished processling {0} lines", lineCount);
}
finally
{
try { swOutput.Close(); }
catch (Exception) { }
try { bsOutput.Close(); }
catch (Exception) { }
try { fsOutput.Close(); }
catch (Exception) { }
}
}
}
private static IEnumerable<string> validateInput(string inputFile, string sectionStartString, string sectionEndString, string outputFolder)
{
if (!File.Exists(inputFile))
yield return string.Format("{0} doesn't exist.", inputFile);
if (string.IsNullOrEmpty(sectionStartString))
yield return string.Format("section start string empty.", inputFile);
if (string.IsNullOrEmpty(sectionEndString))
yield return string.Format("section end string empty.", inputFile);
if (string.IsNullOrEmpty(outputFolder))
yield return string.Format("output folder missing.", inputFile);
if(!Directory.Exists(outputFolder))
yield return string.Format("output folder missing.", inputFile);
}
}
}