我在项目中使用CSVReader读取windows服务中的.csv文件。我们将.csv文件传递给CSVReader以处理该文件,它运行良好。但最近我们决定将csv文件保存到数据库表中,并从中读取。当用户提交csv文件进行处理时,我们的aspx页面将读取csv文件并将其转换为字节数组并保存到数据库中。并且该服务将读取该表并获取字节数组并将其转换为Filestream。此流将传递给CSVReader以进行进一步的工作。现在它为最后一行最后一列抛出错误。只有在保存和读取数据库后才会发生这种情况。我得到以下错误。不知道如何解决这个问题。
"CSV在记录"9"字段"3"附近的位置"494"处似乎已损坏。当前原始数据:">
听说就是密码正在将文件转换为字节数组。。。。。
try
{
fs = new FileStream(filepath, FileMode.Open);
fsbuffer = new byte[fs.Length];
fs.Read(fsbuffer, 0, (int)fs.Length);
}
正在从数据库读取到字节数组。。。。。。
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, ','))
我无法重新创建您的问题,因此,在没有看到从头到尾的保存和加载的情况下,我建议尝试以下方法进行检索:
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和参数替换为用于返回数据的任何sql。
此方法使用SqlDataReader
从适当的行(在我的示例中由rowId标识)和列(在我示例中称为CSVData
)中顺序读取字节,这应该可以避免中途出现任何截断问题(可能是DataTable对象只返回第一个n
字节)。MemoryStream对象可以用于将CSV文件重新保存到文件系统中进行测试,也可以直接输入到CSVReader中。
如果你可以发布你的Save
方法(在那里你实际上将数据持久化到数据库中),那么我们也可以检查一下,以确保那里也没有发生截断。
我现在可以提出的另一个建议是将文件加载到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);