roker002
Commander
- Registriert
- Dez. 2007
- Beiträge
- 2.075
Ich habe ein Programm geschrieben, dass die Datei in mehrere kleinere Dateien splittet. Ich suche jeweils nach Zeilenende und splitte den den Text.
Wenn ich es Synchron mache, funktioniert alles wunderbar. Der Nachteil, der ist langsam wenn man große Dateien splitten will. Daher habe ich das ganze Asynchron geschrieben. Das splitten geht auch, aber ich bekomme nur in der letzte Datei lesbare Zeichen (Falscher Zeichencode?).
Einige Sachen sind extra ausgeschrieben um besser zu debuggen!
Ich habe schon BinaryWriter versucht mit bestimmten encodings aber es geht immer noch nicht!
Wenn ich es Synchron mache, funktioniert alles wunderbar. Der Nachteil, der ist langsam wenn man große Dateien splitten will. Daher habe ich das ganze Asynchron geschrieben. Das splitten geht auch, aber ich bekomme nur in der letzte Datei lesbare Zeichen (Falscher Zeichencode?).
Code:
public static void SplittFile(SqlString path, long size)
{
List<BackgroundWorker> list = new List<BackgroundWorker>();
using (FileStream fs = new FileStream(path.Value, FileMode.Open, FileAccess.Read))
{
fs.Seek(0, SeekOrigin.Begin);
using (StreamReader r = new StreamReader(fs, Encoding.Default))
{
/// Get min Count for splitting the file depends on File Stream Size and cut Size
double l1 = (double)fs.Length / (double)size;
long len = (long)Math.Round((l1) + .5);
for (int i = 1; i <= len; i++)
{
BackgroundWorker bgw = new System.ComponentModel.BackgroundWorker();
bgw.DoWork += new System.ComponentModel.DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerAsync(new SplitFileInfo(path.Value, size, i, (i-1)*size, r.CurrentEncoding));
list.Add(bgw);
}
while (true)
{
var l = new BackgroundWorker[list.Count];
list.CopyTo(l);
foreach (var w in l)
{
if (w != null)
{
if (w.IsBusy == false)
list.Remove(w);
}
}
if (list.Count == 0)
break;
}
}
}
}
static void bgw_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
var info = e.Argument as SplitFileInfo;
long size = info.Size;
if (info.StartPosition ==0)
{
}
using (FileStream fs = new FileStream(info.Path, FileMode.Open, FileAccess.Read))
{
long pre_write_pos = info.StartPosition;
long nextbreak = 0;
byte[] write;
fs.Seek(0, SeekOrigin.Begin);
System.Text.Encoding encoder = info.Encoder;
using (var r = new StreamReader(fs, encoder))
{
if (pre_write_pos + size > fs.Length)
{
if (pre_write_pos > fs.Length)
{
pre_write_pos = fs.Length - (pre_write_pos - fs.Length);
size = fs.Length - pre_write_pos - 1;
}
else
{
size = fs.Length - pre_write_pos - 1;
}
}
fs.Seek(pre_write_pos, SeekOrigin.Begin);
String s = r.ReadLine();
if (s != null)
{
long len = s.ToCharArray().LongLength;
pre_write_pos += len;
size -= len;
}
fs.Seek(pre_write_pos + size, SeekOrigin.Begin);
s = r.ReadLine();
if (s != null)
{
nextbreak = s.ToCharArray().LongLength;
byte[] output = new byte[size + nextbreak];
fs.Seek(pre_write_pos, SeekOrigin.Begin);
if (fs.Read(output, 0, output.Length) != 0)
{
String fn = Path.Combine(Path.GetDirectoryName(info.Path), Path.GetFileNameWithoutExtension(info.Path));
String p = String.Concat(fn, "_", info.Number, System.IO.Path.GetExtension(info.Path));
s = encoder.GetString(output, 0, 4);
if (s.Contains("\r\n"))
{
write = new byte[output.LongLength - 2];
write = output.Skip(2).ToArray();
}
else if (s.Contains("\r") || s.Contains("\n"))
{
write = new byte[output.LongLength - 4];
write = output.Skip(4).ToArray();
}
else
{
write = output;
}
using (var w = new FileStream(p, FileMode.Create, FileAccess.Write))
{
w.Write(write, 0, write.Length);
}
//File.WriteAllBytes(p, write);
}
}
else
{
Console.WriteLine(info);
}
}
}
}
Einige Sachen sind extra ausgeschrieben um besser zu debuggen!
Ich habe schon BinaryWriter versucht mit bestimmten encodings aber es geht immer noch nicht!