In C# (.NET 4.0 in esecuzione su Mono 2.8 su SuSE) Vorrei eseguire un comando batch esterno e acquisire la sua uscita in formato binario. Lo strumento esterno che uso è chiamato 'samtools' (samtools.sourceforge.net) e tra le altre cose può restituire i record da un formato di file binario indicizzato chiamato BAM.Acquisizione dell'output binario da Process.StandardOutput
Utilizzo Process.Start per eseguire il comando esterno e so che posso acquisire l'output reindirizzando Process.StandardOutput. Il problema è che è un flusso di testo con una codifica, quindi non mi dà accesso ai byte grezzi dell'output. La soluzione quasi funzionante che ho trovato è quella di accedere al flusso sottostante.
Ecco il mio codice:
Process cmdProcess = new Process();
ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
cmdStartInfo.FileName = "samtools";
cmdStartInfo.RedirectStandardError = true;
cmdStartInfo.RedirectStandardOutput = true;
cmdStartInfo.RedirectStandardInput = false;
cmdStartInfo.UseShellExecute = false;
cmdStartInfo.CreateNoWindow = true;
cmdStartInfo.Arguments = "view -u " + BamFileName + " " + chromosome + ":" + start + "-" + end;
cmdProcess.EnableRaisingEvents = true;
cmdProcess.StartInfo = cmdStartInfo;
cmdProcess.Start();
// Prepare to read each alignment (binary)
var br = new BinaryReader(cmdProcess.StandardOutput.BaseStream);
while (!cmdProcess.StandardOutput.EndOfStream)
{
// Consume the initial, undocumented BAM data
br.ReadBytes(23);
// ... ulteriori analisi segue
Ma quando ho eseguito questo, le prime 23bytes che ho letto non sono i primi 23 byte nel ouput, ma piuttosto da qualche parte diverse centinaia di migliaia di byte a valle. Presumo che StreamReader faccia un po 'di buffering e quindi il flusso sottostante è già avanzato, diciamo 4K nell'output. Il flusso sottostante non supporta la ricerca fino all'inizio.
E sono bloccato qui. Qualcuno ha una soluzione funzionante per eseguire un comando esterno e catturare il suo stdout in formato binario? L'uscita potrebbe essere molto grande, quindi mi piacerebbe trasmetterlo in streaming.
Qualsiasi aiuto apprezzato.
A proposito, la mia soluzione attuale è quella di avere samtools restituire i record in formato testo, quindi analizzarli, ma questo è piuttosto lento e spero di accelerare le cose usando direttamente il formato binario.
L'unica cosa che riesco a pensare a mano a mano sarebbe quella di impostare la codifica desiderata su Unicode e quindi separare ogni carattere dallo StreamReader in due byte. Quale sarebbe un attacco orribile, e probabilmente fallirebbe miseramente se l'output avesse un numero dispari di byte. Una soluzione alternativa sarebbe implementare la propria codifica che mappa i byte direttamente ai loro rispettivi valori di char, come ASCII ma senza convertire il set superiore in "?". Ma lascerò che qualcun altro fornisca una risposta adeguata. :) – cdhowie