2010-12-16 32 views
4

アップロードされたcsvファイルを保存する前に、解析するかどうかチェックします。私がちょうどファイルをすべて保存していたときに、それが最初に読み込まれたので、保存されたファイルは空白になりました。ここで保存する前にHttpPostedFileを読み込むと、ASP.NET MVCに空のファイルが保存されます

は私のアクションメソッド

[HttpPost] 
public ActionResult Import(HttpPostedFileBase file) 
{ 
    // Check parse went ok 
    using (var fileStream = file.InputStream) 
    { 
     if (!MemberFileParsingService.CheckFileWillParse(fileStream)) 
     { 
      ViewBag.Message = "There was a problem with the file"; 
      return View(); 
     } 
    } 

    // Save file so we can work on it in next action 
    file.SaveAs(Server.MapPath(fileName)); 

    return RedirectToAction("ImportMatch", new { club = ActiveClub.Url }); 
} 

であり、ここでファイルがOK解析しているかどうかをチェックし、私の方法です。 CsvReaderを使用してファイル全体を読み取って、エラーがないことを確認します。 CsvReaderは、ファイルの不良ビットについて例外をスローします。

public static bool CheckFileWillParse(Stream fileStream) 
{ 
    try 
    { 
     using (var reader = new StreamReader(fileStream)) 
     { 
      using (CsvReader csv = new CsvReader(reader, false)) 
      { 
       while (csv.ReadNextRecord()) { } 
      } 
     } 
    } 
    catch(Exception) 
    { 
     return false; 
    } 
    return true; 
} 

私はファイルの終わりに今ある同じストリームを使ってファイルを書き込むしようとしているので、それはおそらくだと思います。私はストリームをリセットする方法を知らない。使用しているすべてのステートメントがその問題を解決することを期待していました。

ストリームをリセットするにはどうしたらいいですか、それともちょうど赤ちゃんですか?

更新:ので、ちょうど赤ニシンで、ストリームが実際に何らかの形でブランクされているストリームをリセットするように見えるがCheckFileWillParseを経て、ストリームの長さがゼロにリセットされるが見つかりました。

+0

HttpInputStreamオブジェクトからStreamReaderを作成し、ヘッダーが正しいことを確認するための行を読み込んだり、ストリームを(第三者のライブラリに)再利用したりする場合も同じことが起こります。ファイルの先頭を探したり、その行を返すことはできないようです。最も迷惑な! –

答えて

2

Stream.CopyTo()を使用して、分析するストリームのコピーを作成することを検討しましたか?

+0

これは簡単かもしれません。 @Briansの解決策を作るためにいくつかの調整を試してみると、これが試されます。 –

+0

元のストリームを元に戻すことができれば、よりクリーンなソリューションになります。私はあなたがどのように乗り出すか見ることに興味があります。 – kim3er

+0

ストリームを閉じたときに、CheckFileWillParseでストリームがブランキングされていたので、ストリームをコピーするという考えが最良だったので、関数に渡されたストリームは変更されませんでした。 –

3

(可能であれば)ストリームを巻き戻す必要があります。読んでいると、現在の位置はストリームの終わりにあります。そのため、ファイルを保存するとファイルが空になっています。

これを行うには、Seek関数またはPositionプロパティを使用できます(0に設定します)。すべてのストリームタイプがこれをサポートしているわけではありません。

ストリームタイプでサポートされていない場合は、最初にディスクにファイルを書き出してからテストを実行する必要があります。

+0

これは、fileStream.Seek(0、SeekOrigin.Begin)を検索しても追加することはできませんでした。何らかの理由でCheckFileWillParseの後にストリームの長さが0になっている可能性があります。 –

+1

赤ちゃんの姿勢が変わった。名前を付けて保存すると、位置自体がリセットされます。ストリームリーダーを閉じることによってストリームが消去されたことが分かります。 –

+0

あなたが正しいです、私はあなたがStreamReaderを閉じていたことに気づいたはずです。あなたがそれをしたとき、それは基本的な流れを閉じた。私は以前にその問題にぶつかってきました。あなたがそれを理解してうれしい! –

2

StreamReader Disposeメソッドは、基になるStreamも破棄します。そのためusing文の

MemoryStream ms = new MemoryStream(); 
myStream.CopyTo(ms); 
myStream.Position = ms.Position = 0; // !Don't forget this! 
//And then read your 'ms' here 
+0

私のために働いた、ありがとう。 –

2

、あなたのStreamReaderオブジェクト上Dispose()メソッドが呼び出されます。これにより、実際には下にあるStreamオブジェクトが閉じられます。したがって、なぜストリームの長さがゼロであるのか。

オプション1:

1つのオプションは、usingステートメントを除去することにより、StreamReaderインスタンスを処分しないことです。後でストリームを手動で処分する必要がありますが(CsvReader)、そのDispose()メソッドを呼び出すことでストリームを処分する必要があります。

ガベージコレクタはStreamReaderオブジェクトをクリーンアップし、基本ストリームを閉じることはありません。

オプション2:

StreamReaderをインスタンス化するときは、following constructorを使用することができます。

public StreamWriter(
    Stream stream, 
    Encoding encoding, 
    int bufferSize, 
    bool leaveOpen 
) 

trueleaveOpenパラメータを設定すると、ストリームがクローズされないことを保証します。

+0

そのコンストラクタはStreamWriter用です。 –

関連する問題