Ранее реализованный код принимает файл xls и сохраняет его в столбце таблицы, используя поток. Я использую тот же метод, но единственное изменение заключается в том, что сохраненный файл представляет собой файл типа xlsm или xlsx, который он сохраняет в столбце в таблице. база данных
Когда я пытаюсь получить содержимое из базы данных и выбрасываю сохраненный файл xlsm или файл xlsx, я получаю сообщение об ошибке "Файл Excel обнаружил нечитаемое содержимое. Вы хотите восстановить содержимое этой рабочей книги?"
Вот код для сохранения файла xlsm или xlsx
System.IO.Stream filestream = System.IO.File.Open(file, System.IO.FileMode.Open);
int fileLength = (int)filestream.Length;
byte[] input = new byte[fileLength];
filestream.Read(input, 0, fileLength);
string Sql = "insert into upload values(@contents)";
con.Open();
System.Data.SqlClient.SqlCommand c = new System.Data.SqlClient.SqlCommand(Sql, con);
c.Parameters.Add("@contents", System.Data.SqlDbType.Binary);
c.Parameters["@contents"].Value = input;
c.ExecuteNonQuery();
Чтобы получить и отправить пользователю
SqlCommand comm = new SqlCommand("select contents from upload order by id desc", con);
SqlDataReader reader = comm.ExecuteReader();
int bufferSize = 32768;
byte[] outbyte = new byte[bufferSize];
long retval;
long startIndex = 0;
startIndex = 0;
retval = reader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
while (retval > 0)
{
System.Web.HttpContext.Current.Response.BinaryWrite(outbyte);
startIndex += bufferSize;
if (retval == bufferSize)
{
retval = reader.GetBytes(2, startIndex, outbyte, 0, bufferSize);
}
else
{
retval = 0;
}
}
Ответ 1 · samjudson
Несколько вещей кажутся мне возможными.
Во-первых, вы не звоните reader.Read().
Во-вторых, нет необходимости в проверке на retval == bufferSize - достаточно снова вызвать GetBytes, и он вернет 0, если из поля не было прочитано ни одного байта.
В-третьих, когда вы пишете в HttpResponse, вам нужно убедиться, что вы вызываете Response.Clear() перед записью байтов в вывод и Response.End() после записи файла в ответ.
Еще одна вещь, которую стоит попробовать, - это сохранить файл на жесткий диск и сравнить его с оригиналом. Это тот же размер? Если он больше, то вы записываете в файл слишком много информации (см. предыдущие комментарии о HttpResponse). Если он меньше, значит, вы пишете недостаточно и, скорее всего, выходите из цикла слишком рано (см. комментарий к retval).
Ответ 2 · John Saunders
Я не мог не заметить количество мест, где ваш код не смог обернуть IDisposable в блок using, например:
using (SqlConnection con = new SqlConnection(connectionString))
{
byte[] input;
using (System.IO.Stream filestream = System.IO.File.Open(file, System.IO.FileMode.Open))
{
int fileLength = (int)filestream.Length;
input = new byte[fileLength];
filestream.Read(input, 0, fileLength);
}
const string Sql = "insert into upload values(@contents)";
con.Open();
using (System.Data.SqlClient.SqlCommand c = new System.Data.SqlClient.SqlCommand(Sql, con))
{
c.Parameters.Add("@contents", System.Data.SqlDbType.Binary);
c.Parameters["@contents"].Value = input;
c.ExecuteNonQuery();
}
using (SqlCommand comm = new SqlCommand("select contents from upload order by id desc", con))
{
using (SqlDataReader reader = comm.ExecuteReader())
{
int bufferSize = 32768;
byte[] outbyte = new byte[bufferSize];
long retval;
long startIndex = 0;
startIndex = 0;
retval = reader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
while (retval > 0)
{
System.Web.HttpContext.Current.Response.BinaryWrite(outbyte);
startIndex += bufferSize;
if (retval == bufferSize)
{
retval = reader.GetBytes(2, startIndex, outbyte, 0, bufferSize);
}
else
{
retval = 0;
}
}
}
}
}