Ребятки, столкнулся с проблемой, которую просто не в состоянии осмыслить. Пытаюсь написать на Visual Basic программу, которая читала бы содержимое файла, передавала его в переменную и далее передавала SQL-запросом в поле таблицы на сервер. Т.к. я не программист, ищу простых решений. И казалось бы - нашёл. Есть функция () (или метод - не знаю), которая читает содержимое файла в двоичном виде в массив:
FileContent = My.Computer.FileSystem.ReadAllBytes(FileName)
Есть функция, которая преобразует двоичный массив в строку:
FileContentString = System.Text.Encoding.Default.GetBytes(FileContent).
Далее должна идти конкатенация текстовой строки с использованием FileContentString (формирование текста sql-команды для передачи на сервер), но я столкнулся с проблемой: конструкция
Variable = textString1 + FileContentString + textString2
(во избежание ПРОСТЫХ ответов: пробовал и так:
Var1 = "TextStr1"
Var2 = "TextStr2"
Variable = Var1 + "'" + FileContrntString + "'" + Var2, и так:
Variable = Var1 & "'" & FileContrntString & "'" & Var2) -
наглухо игнорируется средой в том плане, что обрезается всё, что правее строки, полученной преобразованием из двоичного массива с помощью функции System.Text.Encoding.Default.GetBytes(FileContent). Я просто не в состоянии осмыслить, почему так происходит. Ребята, если тут есть программисты (а я знаю, что вы тут есть) - помогите!..
Комментарии
Там вместо + нужно использовать &
ну, ещё может зависеть от содержимого файла. Есть ли там пробел. Может с кодировкой что не так. Странная конструкция с text encoding default(что этот default)
что этот default
Тот что в системе по умолчанию. В русской винде, будет 1251
Пробовал и +, и &, и как в тексте статьи - левую часть отдельной переменной, правую отдельной - получается так, что при исполнении кода обрезается всё, что правее строки, полученной этим методом (функцией). Пробовал с помощью этих функций читать файл в массив - потом в строку - потом обратно в массив (System.Text.Encoding.Default.GetBytes), потом записывать в другой файл в бинарном виде - всё проходит на ура, пока не пытаюсь соединить полученную этим методом строку с чем-то ещё. В исходном файле (doc) - и текст, и изображение, всё нормально... Не понимаю, то ли это глюк функции, то ли глюк среды... Default в данном случае значит использовать текущую системную кодировку...
Если содержимое не только цифры, то нужно проверять на наличие кавычек, и менять их на что-нибудь ещё.
также перезагрузите excel или word) можно использовать функцию
Попробую. Но это же не VBA, а VB...
В vba ещё и регулярные выражения есть))
Я не програмист, но из моего опыта строка должна выглядеть так:
Variable = '"textString1"' & '"FileContentString "' & '"textString2"'
Как-то так:
var1 = "textString1"
var2 = "textString2"
Variable = var1 + "'" + FileContentString + "'" + var2 или
Variable = var1 & "'" & FileContentString & "'" & var2
Это всё я пробовал. Вопрос не в том, как соединить текстовые строки, а в том, почему при использовании КОНКРЕТНОЙ функции обрезается всё, что стоит справа от переменной, которой присвоено значение этой самой функции... С конкатенацией-то я разобрался, а вот в чём тут проблема - понять не могу... :(
Дело наверно в кодировке. Попробуй UTF-8 вместо default.
Пробовал. Дело, как мне кажется, на 99% не в кодировке - как я написал, при работе с файлами, т.е. тогда, когда я не пытаюсь соединять строки, всё работает идеально, а когда я пытаюсь что-либо присвоить СПРАВА от строки, полученной с помощью описанной функции - всё идёт по... :((( Пробовал разные кодировки - содержимое строки меняется, А СПРАВА ОТ НЕЁ - всё обрезается как х... бритвой... :(
Я бы использовал https://msdn.microsoft.com/ru-ru/library/ms128028(v=vs.110).aspx
FileSystem.ReadAllText (String)
Да, но мне нужно считать файл именно как binary - потому что содержимое файла может быть далеко не только текстовым...
https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/l...
Попробуйте эту функцию. То что вы используете не преобразует байты в строку.
Дык :)) Я её и использую.
System.Text.Encoding.Default.GetBytes(FileContent). вот это вы используете
Ниже написал. GetString для преобразования массива в строку.
encoding.default.GetString(FileContent)
Я
непрограммист, но подобные задачи решается по-другому, вообще без кода.Если файл содержит строки, каждая из которых должна попасть в строку таблицы БД, то берете ексель, открываете файл, пишете в свободном столбце формулу "UPDATE TABLE ..." & An, а потом выполняете полученные запросы в СУБД.
У меня задача - запихать файл (любой) в поле таблицы. Соответственно, в таблице есть поле типа varbinary, и программа должна читать файл в двоичном виде. Как-то так.
Лет пять назад я подобное в потоке открывал-отправлял, но не в васике, конечно )
Народ, я прошу прощения, я опубликую кусок кода:
SourceFileName = "D:\BD\SQLDB\texttrying\source.doc" - определяю имя файла для чтения
FileContent = My.Computer.FileSystem.ReadAllBytes(SourceFileName) - читаю файл в массив в бинарном виде
FileContentString = System.Text.Encoding.Default.GetString(FileContent) - преобразую массив байтов в строку
далее пытаюсь работать с переменной FileContentString - и возникает описанная ситуация. Всё, что правее её в конкатенации - наглухо режется (не понимаю, чем и почему). Простите, люди, сам запутался, и вас запутал :(
Строка это строка, а бинарные данные это бинарные данные и их в строку смысла нет переводить, ведь как только встретится ноль, то строка обрежется (зависит от языка).
Более того, мешанину из непечатных символов не имеет смысла в базу пихать.
У вас проблема с постановкой задачи, она неверная, так не делают.
Скажите что конкретно вы хотите достичь.
Хочу (нужно) запихать содержимое файла (конкретно - рабочей программы, как правило, это файлы word) и хранить в базе MS sql server. Для этого я создал таблицу на сервере с полями типа varbinary и пытаюсь файлы читать и передавать на сервер. И извлекать из таблицы без потерь форматирования. И всё бы получилось (независимо от того, правильно или неправильно я действую,) если бы не возникла описанная в тексте статьи проблема...
кроме ноля может встретиться символ конца файла. но мне кажется в запрос Вы не сможете впихнуть файл произвольной длины (даже если перевести его в 16-ричный вид), т.к. длина запроса ограничена, SQL запросто обрежет команду на 4-8 кб текста. У поля типа бинари должен быть соответствующий метод чтения данных из файла, вот им и пользуйтесь.
Да ничего подобного. Я пробовал раньше текст из буфера обмена присваивать в переменную - всё получалось. в SQL Server всё тоже передавалось без проблем - независимо от длины текста. При использовании описанных функций, если ничего не пробовать прибавлять к переменным, содержимое этих переменных прекрасно передаётся из файла в файл - а вот при попытке конкатенации СПРАВА всё режется. Тоже пробовал на файлах разного размера и типа. Так что мутно всё...
ничего бы и не получилось.
с банарными данными надо и работать как с бинарными данными.
при этом файлы хранить в базе это плохой тон (скорость, размер и прочее), обычно файл на диске, а в базе путь/имя файла.
никогда не заталкивал файлы и не уверен как это делается, возможно нужет тип данных BLOB.
тут есть пример:
https://stackoverflow.com/questions/1120689/how-can-i-insert-binary-file...
INSERT INTO Files
(FileId, FileData)
SELECT 1, * FROM OPENROWSET(BULK N'C:\Image.jpg', SINGLE_BLOB) rs
Всё это я прошёл. Openrowset не умеет считывать данные из ПРОИЗВОЛЬНЫХ файлов - у меня не получилось. По-моему, корректно он читает ТОЛЬКО текстовые файлы. Именно поэтому чтение и представление того, что передаётся в запрос, пытаюсь возложить на приложение. BLOB - это и есть varbinary (max) в терминологии SQL SERVER... Именно поэтому я читаю содержимое файла как binary, именно поэтому всякие преобразования использую. Вопрос в другом - почему ИМЕННО эта функция как будто обрезает любые выражения, что написаны СПРАВА от переменной, полученной при использовании этой самой функции. Это очень странно.Про хранение ФАЙЛОВ в БД - это отдельный вопрос. В любом случае, сейчас мне без этого не обойтись.
но ваш способ тоже работать не будет, даже есть вы запихаете, то восстановить скорее не сможете, потому что преобразование обычно НЕобратимо.
например, строка обрезается как только встретился ноль ибо это код окончания строки.
кстати, бинарные данные в виде строки можно сохранить, но в кодированом виде, например используя BASE64, вот тогда проблем, кроме размера, не будет.
Спасибо. Я в конце концов всё равно разберусь :) Но вот этот случай меня просто из себя вывел - я просто НЕ МОГУ ПОНЯТЬ, ЧТО ИДЁТ НЕ ТАК :))) Насчёт нулей как окончание строки - сейчас, как я понял, есть методы, которые считывают файл ЦЕЛИКОМ, так что этого, наверное, можно не опасаться... Но вот, как выясняется, у них есть свои...хм... ЗАМОРОЧКИ... :)) А бинарные данные в базу я уже пихал. работает. Только вот форматирование текста теряется при преобразовании из varbinary в varchar - это я и пытаюсь обойти...
вы просто неправильно используете, потому и лезут проблемы.
считывается то весь файл и помещается в память как строка, а потом при считывании программы натыкается на ноль и воспринимает это как окончание строки ибо так строки и работают. всё просто. а вот если использовать BASE64, то нулей не будет, но места больше занимать будет.
Хм. Интересно. А что с этим сделать можно? Интерпретатор(?) ЛЮБОЙ 0 воспринимает как окончание команды? Как использовать BASE64 - я просто не знаю... Буду благодарен, если подскажете...
я VB не знаю и исхожу из того, что работает аналогично C++
соответсвено как прикрутить BASE64 не подскажу, но гугл подсказывает:
важно именно бинарные данные подавать, а не вашу строку.
Я не знаю, конечно, содержимого этой строки, но, т.к. она формируется на основе именно бинарных данных (строка получается преобразованием БИНАРНОГО массива в СТРОКУ(?) - наверное, бинарную), то логично предположить , что строка - представляет собой бинарные данные. За подсказку - спасибо огромное :)
я имел в виду, что в строку преобразовывать не надо, т.е. этот вызов не только не нужен, но и вреден: System.Text.Encoding.Default.GetString
в Base64 БИНАРНЫЕ данные передаются, строки тоже можно, но это в редких случаях
Спасибо за подсказку. Всё оказалось проще, чем казалось. :) Кстати, насчёт OPENROWSET я был неправ - всё он умеет считывать, это просто я неправильно извлекал. Что поделаешь, не программист, а учиться на ходу - непросто...
именно так. BASE64 encoding - и никаких бинарных нулей, спецсимволов и прочей дряни, чистый ASCII, как слеза комсомолки.
Перспективный чат детектед! Сим повелеваю - внести запись в реестр самых обсуждаемых за последние 4 часа.
Может посмотреть что получилось msgbox(string) после импорта из двоичного файла?
попробую
Вот такая вот фигня...
Не знаю конечно что за базу вы используете, но MSSQL и ORALE имеют тип blob - его использование самое простое решение в вашем случае (если ваша СУБД поддерживает этот тип). В Basic работа с этим типом осуществляется через ado.stream (если мне память не изменяет).
По вашей проблеме подсказать конкретно в чем проблема - невозможно. Необходим полный текст ваших процедур, какая база, тип поля куда пихаете данные и т.д.,
Навскидку - обрезание массивов (права, слева или вообще) - говорит о том, что вы некорректно с ними работаете. К примеру - некорректно выделяете под него память, если он динамический.
И т.д.
Могу скинуть на почту весь проект.
кидайте.
завтра посмотрю чем можно помочь
Сделаю наверное проще. Завтра до обеда я вам скину действующий пример записи файла в базу (в поле blob).
Правда пример будет на связке Паскаль - Oracle.
А... куда кидать-то? :).....
кинул мыло в личку
Ответил. Спасибо.
Я разберусь. Спасибо огромное. Если что - кидайте код прямо в личку. Спасибо! :)
Вижуалвасик не знаю и знать не хочу.
Но знаю, что как минимум у Оракла есть… скажем так «особенности» в процедуре записи в базу бинарного объекта (простой INSERT/UPDATE не прокатывает).
Ну и с учётом взаимоотношений майкросовта с ораклом, в случае использования вижуалвасика может получиться… интересно.
Это и у MS SQL так. Иначе и париться не имело бы смысла - select - и всё :)
Простой insert/update там действительно не прокатит, однако ничего сверхсложного там нет
Страницы