3

プロジェクトでCSVReaderを使用して、Windowsサービスで.csvファイルを読み取ります。ファイルを処理するために.csvファイルをCSVReaderに渡し、正常に機能していました。しかし最近、csvファイルをデータベーステーブルに保存してそこから読み取ることにしました。ユーザーが処理のためにcsvファイルを送信すると、aspxページがcsvファイルを読み取り、それをバイト配列に変換してデータベースに保存します。サービスはテーブルを読み取り、バイト配列を取得してFilestreamに変換します。このストリームは、さらなる作業のためにCSVReaderに渡されます。これで、最後の行の最後の列に対してエラーがスローされます。これは、データベースを保存して読み取った後にのみ発生します。次のエラーが発生します。これを修正する方法がわかりません。

「CSVは、位置「494」のレコード「9」フィールド「3」の近くで破損しているようです。現在の生データ:」

Hearは、ファイルをバイト配列に変換するコードです....。

try
{
     fs = new FileStream(filepath, FileMode.Open);
     fsbuffer = new byte[fs.Length];
     fs.Read(fsbuffer, 0, (int)fs.Length);
}

DBからバイト配列への読み取り.....。

myobject.FileByteArray = ObjectToByteArray(row);

public byte[] ObjectToByteArray(DataRow row)
        {
            if (row["fileBytearray"] == null)
                return null;
            try
            {
                BinaryFormatter bf = new BinaryFormatter();
                System.IO.MemoryStream ms = new System.IO.MemoryStream();

                bf.Serialize(ms, row["fileBytearray"]);
                return ms.ToArray();
            }
    }

Stream fileStream = new MemoryStream(myobject.FileByteArray)
using (CsvReader csv = 
                        new CsvReader(new StreamReader(fileStream, System.Text.Encoding.UTF7), hasHeader, ','))
4

1 に答える 1

2

問題を再現できなかったため、代わりに、最初から最後まで保存と読み込みを確認せずに、次の検索を試すことをお勧めします。

public MemoryStream LoadReportData(int rowId)
{

  MemoryStream stream = new MemoryStream();

  using (BinaryWriter writer = new BinaryWriter(stream))
  {

    using (DbConnection connection = db.CreateConnection())
    {
      DbCommand selectCommand = "SELECT CSVData FROM YourTable WHERE Id = @rowId";

      selectCommand.Connection = connection;

      db.AddInParameter(selectCommand, "@rowId", DbType.Int32, rowId);
      connection.Open();

      using (IDataReader reader = selectCommand.ExecuteReader(CommandBehavior.SequentialAccess))
      {

        while (reader.Read())
        {

          int startIndex = 0;
          int bufferSize = 8192;

          byte[] buffer = new byte[bufferSize];

          long retVal = reader.GetBytes(0, startIndex, buffer, 0, bufferSize);

          while (retVal == bufferSize)
          {

            writer.Write(buffer);
            writer.Flush();

            startIndex += bufferSize;
            retVal = reader.GetBytes(0, startIndex, buffer, 0, bufferSize);

          }

          writer.Write(buffer, 0, (int)retVal);
        }

      }

    }
  }

  return stream;

}

selectCommand sqlおよびparametersを、データを返すために使用しているsqlに置き換える必要があります。

このメソッドは、を使用しSqlDataReaderて、適切な行(私の例ではrowIdで識別されます)と列(CSVData私の例では呼び出されます)からバイトを順番に読み取ります。これにより、途中で切り捨ての問題が回避されます(DataTableオブジェクトが返されるのは最初のnバイト)。MemoryStreamオブジェクトを使用して、CSVファイルをテスト用のファイルシステムに再保存するか、CSVReaderに直接フィードすることができます。

メソッド(実際にデータをデータベースに永続化する場所)を投稿できる場合はSave、それもチェックして、そこで切り捨てが発生していないことを確認できます。

私が今できるもう1つの提案は、ファイルをbyte配列にロードすることです。ファイルを一度にロードする場合は、次のように置き換えるだけです。

try
{
     fs = new FileStream(filepath, FileMode.Open);
     fsbuffer = new byte[fs.Length];
     fs.Read(fsbuffer, 0, (int)fs.Length);
}

byte[] fileBytes = File.ReadAllBytes(filepath);
于 2012-10-15T08:48:49.010 に答える