2012-04-16 12 views
1

私は大きなゲノムの配列を得て、これを小さな.txtファイルに分割する必要があります。大きなtxtファイルを特定のコンテンツに基づいて小さなものに分割する

シーケンスは、この

>supercont1.1 of Geomyces destructans 20631-21 
AGATTTTCTTAATAACTTGTTCAATGTGTGTTCAAATGATATGCCGTGATGTATGTAGCA 
TAAACAGATGTAGTAGAAGAGTTTGCAGCAATCGTTGAGTAGTATTGCTTCTGTTGTTGG 
>supercont1.2 of Geomyces destructans 20631-21 
AGATTTTCTTAATAACTTGTTCAATGTGTGTTCAAATGATATGCCGTGATGTATGTAGCA 
TAAACAGATGTAGTAGAAGAGTTTGCAGCAATCGTTGAGTAGTATTGCTTCTGTTGTTGG 
TAAACAGATGTAGTAGAAGAGTTTGCAGCAATCGTTGAGTAGTATTGCTTCTGTTGTTGG 
>supercont1.3 of Geomyces destructans 20631-21 
AGATTTT (...) 

のように見え、それが名前の小さなファイルに分割されるべきである: "1.1-Geomyces-destructans - 20631から21"、 "1.2-Geomyces ..." ゲノムと成就しますデータ。 @JimMischelのヘルプがどのように見える

私のコードの後:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.IO; 

namespace genom1 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     string filter = "Textové soubory|*.txt|Soubory FASTA|*.fasta|Všechny soubory|*.*"; 

     private void doit_Click(object sender, EventArgs e) 
     { 
      bar.Value = 0; 

      OpenFileDialog opf = new OpenFileDialog(); 

      // filter for choosing file types 
      opf.Filter = filter; 

      string lineo = "error"; // test 

      if (opf.ShowDialog() == DialogResult.OK) 
      { 
       var lineCount = 0; 
       using (var reader = File.OpenText(opf.FileName)) 
       { 
        while (reader.ReadLine() != null) 
        { 
         lineCount++; 
        } 
       } 

       bar.Maximum = lineCount; 
       bar.Step = 1; 

       FolderBrowserDialog fbd = new FolderBrowserDialog(); 

       fbd.Description = "Vyber složku, do které chceš rozdělit načtený soubor: \n\n" + opf.FileName; // dialog desc 
       if (fbd.ShowDialog() == DialogResult.OK) 
       { 
        List<string> lines = new List<string>(); 
        foreach (var line in File.ReadLines(opf.FileName)) 
        { 
         bar.PerformStep(); 

         if (line[0] == '>') 
         { 
          if (lines.Count >= 0) 
          { 
           // write contents of lines list to file 

           //quicker replace for better file name 
           StringBuilder prep = new StringBuilder(line); 
           prep.Replace(">supercont", ""); 
           prep.Replace("of", ""); 
           prep.Replace(" ", "-"); 
           lineo = prep.ToString(); 

           // append or writeall? how to writeall lines without append? 
           //System.IO.File.WriteAllText(fbd.SelectedPath + "\\" + lineo + ".txt", lineo); 
           StreamWriter SW; 
           SW = File.AppendText(fbd.SelectedPath + "\\" + lineo + ".txt"); 

           foreach (string s in lines) 
            { 
             SW.WriteLine(s); 
            } 

           SW.Close(); 

           // and clear the list. 
           lines.Clear(); 
          } 
         } 
         lines.Add(line); 
        } 
        // here, do the last part 
        if (lines.Count >= 0) 
        { 
         // write contents of lines list to file. 

         /* starts being little buggy here... 

         StreamWriter SW; 
         SW = File.AppendText(fbd.SelectedPath + "\\" + lineo + ".txt"); 
         foreach (string s in lines) 
         { 
          SW.WriteLine(s); 
         } 
         SW.Close(); 

         */ 
        } 
       } 

      } 
     } 

    } 
} 

答えて

2

ファイルがメモリに収まる大きさであれば、File.ReadAllTextを呼び出して文字列にすることができます。次に、>文字の間でテキストを抽出します。次のようなものがあります。

string s = File.ReadAllText("filename"); 
int pos = s.IndexOf('>'); 
while (pos != -1) 
{ 
    int newpos = s.IndexOf('>', pos+1); 
    string text = s.Substring(pos+1, newpos - pos); 
    // now write text to a file 

    // update current position 
    pos = newpos; 
} 
// here you'll have to handle the last part of the file specially. 

ファイルの名前を正しく指定することができます。

ファイル全体をメモリに収めることができない場合は、ファイルを1文字ずつ読むか、何らかのバッファリングを行うことができます。 >が常に行の先頭にあることが分かっていれば、問題は簡単です。次に、あなたは書くことができます:

+0

これは素晴らしい応答です!あなたのコメントは本当に私を助けました! まだ1つの質問があります(申し訳ありません) - 私はこの2つのIFについて少し混乱しています。なぜここに最後の部分があるのでしょうか? 私のコードにいくつか変更を加えました。経験豊かな目で見てください。 「> supercont1.1は」「> supercont1.2」などのコンテンツ PSを持っているTXTファイルを生成するには問題があります:それはWriteAllTextかのappendTextを使用することをお勧めしますか?どちらが速いの?私はこのプログラムが本当に大きなファイルを読んでくれることを祈っています。 – user1337432

+0

あなたは 'lines.Count> = 0'ではなく' lines.Count> 0'を望ましくありません。行がない場合は、ファイルを作成する必要はありません。 "最後の部分"の理由は、おそらくファイルが行末に ">"で終わっていない(またはそうであるかもしれない)からです。そうでなければ、ファイルの最後の部分を 'lines'リストにバッファリングして出力する必要があります。 'File.AppendText'は問題ありません。このプログラムが非常に大きなファイルで動作している場合、ディスクの速度によって制限されるため、ロジックを最適化することで大きな違いは生じません。 –

+0

@ user1337432:おそらく 'line'を使ってファイル名を抽出したくないでしょう。代わりに 'lines [0]'を使用してください。これは先頭のマーカーです。だから、私は 'lines.Count> 0'を持っているのです。そして、なぜ私は "最後の部分"を持っているのですか? 'line'を使うと、ラベルは消えます。 –

1

私は最も簡単な方法は、最初File.ReadAllText()を使用してファイル全体を読み取ることがあると思います。次に、String.Split(">")を使用して、新しいファイルの内容と思われる配列を返します。

関連する問題