2014-09-24 2 views
3

Я получаю файл через SFTP-сеанс в службе WCF. Этот файл считывается в объект MemoryStream. Я успешно передал этот поток в файл на диске & подтвердил, что файл успешно передан (это было сделано с использованием FileStream вместо MemoryStream).Дополнительные байты, добавляемые к файлу при сохранении в SQL Server

Но когда я конвертировать этот MemoryStream в byte[], чтобы сохранить его в таблицу SQL Server (с колонкой, объявленного VARBINARY(MAX)), кажется, что 8 байт быть префиксом в файл.

В качестве примера я загрузил .txt-файл, используя службу SFTP SFTP &, сохраненную в базе данных. Затем, используя BCP, я вывожу файл на диск. После открытия файла в первой строке добавляется «U» («U» и 7 пробелов).

То же самое происходит с документами Office. Я сделал ту же процедуру, что и выше, для файла .xls, который на старте 49Kb большой. Но после вывода его с использованием BCP файл поврежден & - 50Kb большой.

Как ни странно, .pdf-файлы, кажется, правильно сохраняют &.

Несколько фрагментов кода я использую:

Для преобразования потока в массив байтов

var stream = (MemoryStream)data; 
stream.Seek(0, SeekOrigin.Begin); 
byte[] m_Bytes = stream.ToArray(); 

Чтобы сохранить массив в SQL Server

cmd.Parameters.Add("@File", System.Data.SqlDbType.VarBinary, -1).Value = file; 

Чтобы экспортировать файл с SQL Server в файл с использованием BCP

bcp "SELECT [File] FROM SFTPUpload.dbo.Upload" queryout "C:\SFTP\Test.txt" -T -N -S Server_Name\Instance_Name 

Может ли это быть проблема с методом, я использую, чтобы сохранить файл в базу данных, или как я извлечения файла с помощью BCP? Последнее кажется более вероятным, так как сохранение файла непосредственно на диске не испортило его.

Любая помощь или совет были бы очень признательны.

ответ

3

BCP записывает данные в формате BCP. Формат BCP должен содержать больше, чем только двоичные данные, поскольку он поддерживает несколько столбцов и строк. Экспортируйте двоичные данные с помощью метода, который точно сохраняет свои байты.

Я предполагаю, что начальные 8 байтов являются длиной блоба.

+0

Вы имеете право на префикс длиной 8 байтов (перегруженный как индикатор NULL) для типов данных varbinary (MAX). –

+0

Отлично, спасибо за быстрый ответ. Я занят составлением приложения-экспортера, чтобы вытащить файлы из БД. И я узнал кое-что о BCP сейчас в процессе ... –

+2

Чтобы подтвердить полноту, после написания приложения-экспортера для экспорта байтов как есть, файлы больше не повреждались. –

3

У меня была такая же проблема, и вот как ее исправить.

В моем примере, я имел таблицу SQL Server под названием «External_File» и один из его полей, ExtFile_Data, был varbinary(max), содержащие исходные данные файла, как правило, из всего файла Excel.

External_File

То, что я хотел сделать, это использовать bcp быстро экспортировать эти исходные данные в файл на нашем сервере базы данных.

Эта команда почти работал отлично ...

-- This does not work - don't use it !! 
EXEC master..xp_cmdshell 'BCP "select ef.ExtFile_Data 
    FROM [External_File] ef WHERE ExtFile_ID = 1005" 
    queryout "G:\ImportData\TestFile.xlsm" -T -N' 

... но он добавил 8 байт в начале каждого файла, так что не может быть открыт ни один из них.

Решение было сделать BCP использовать файл форматирования, который я назвал «BCPformat.fmt» ...

EXEC master..xp_cmdshell 'BCP "select ef.ExtFile_Data 
    FROM [External_File] ef WHERE ExtFile_ID = 1005" 
    queryout "G:\ImportData\TestFile.xlsm" -T 
    -f "G:\ImportData\BCPformat.fmt" ' 

Вот что мой BCPformat.fmt файл выглядел.

10.0 
1 
1 SQLBINARY 0 0 "" 1 ExtFile_Data "" 

Обратите внимание, что ваш файл форматирование должно соответствовать структуры данных, которые вы пытаетесь экспортировать.

В моем случае я экспортировал только один столбец, который называется ExtFile_Data, поэтому это имя поля в моем файле .fmt. Ваши имена полей будут быть разными, поэтому ваш файл .fmt должен будет отразить это.

Но. с этим файлом .fmt на месте (и доступным любым пользователем SQL Server выполняется сценарий), я мог бы успешно экспортировать необработанные данные в файл Excel без этих дополнительных 8 байтов в начале.

И этот метод значительно быстрее при превращении больших кусков необработанных данных SQL Server в реальный файл, чем любой другой метод, который я мог найти.

Это просто нелепо, что bcp не имеет простой флаг дамп varbinary(max) поле в файл без добавляя что-нибудь на этот кусок данных.

Надеюсь, это поможет.

+0

Да, это очень помогает Майку. Более подробную информацию о формате файла можно найти https://docs.microsoft.com/en-us/sql/relational-databases/import-export/non-xml-format-files-sql-server FYI, есть также XML-версия для файлов формата, но проверка XML с помощью BCP не позволит префиксную длину 0 :( – LucasM

Смежные вопросы