Программисты, вас же тут есть! Помогите!..

Аватар пользователя alterlex

Ребятки, столкнулся с проблемой, которую просто не в состоянии осмыслить. Пытаюсь написать на 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). Я просто не в состоянии осмыслить, почему так происходит. Ребята, если тут есть программисты (а я знаю, что вы тут есть) - помогите!..

 

Авторство: 
Авторская работа / переводика

Комментарии

Аватар пользователя Another_jim
Another_jim(9 лет 7 месяцев)

Там вместо + нужно использовать &

ну, ещё может зависеть от содержимого файла. Есть ли там пробел. Может с кодировкой что не так. Странная конструкция с text encoding default(что этот default)

 

Аватар пользователя PigPog
PigPog(12 лет 9 месяцев)

что этот default

Тот что в системе по умолчанию. В русской винде, будет 1251

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Пробовал и +, и &, и как в тексте статьи - левую часть отдельной переменной, правую отдельной - получается так, что при исполнении кода обрезается всё, что правее строки, полученной этим методом (функцией). Пробовал с помощью этих функций читать файл в массив - потом в строку - потом обратно в массив (System.Text.Encoding.Default.GetBytes), потом записывать в другой файл в бинарном виде - всё проходит на ура, пока не пытаюсь соединить полученную этим методом строку с чем-то ещё. В исходном файле (doc) - и текст, и изображение, всё нормально... Не понимаю, то ли это глюк функции, то ли глюк среды... Default в данном случае значит использовать текущую системную кодировку...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя Another_jim
Another_jim(9 лет 7 месяцев)

Если содержимое не только цифры, то нужно проверять на наличие кавычек, и менять их на что-нибудь ещё.

также перезагрузите excel или word) можно использовать функцию 

Replace(varLeft&"наш_шаблон"&varRight, "наш_шаблон", данныеФайла)
Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Попробую. Но это же не VBA, а VB...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя Another_jim
Another_jim(9 лет 7 месяцев)

В vba ещё и регулярные выражения есть))

Аватар пользователя guliaka
guliaka(10 лет 8 месяцев)

Я не програмист, но из моего опыта строка должна выглядеть так:

 

Variable = '"textString1"' & '"FileContentString "' & '"textString2"'

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Как-то так:

var1 = "textString1"

var2 = "textString2"

Variable = var1 + "'" + FileContentString + "'" + var2 или 

Variable = var1 & "'" & FileContentString & "'" & var2

Это всё я пробовал. Вопрос не в том, как соединить текстовые строки, а в том, почему при использовании КОНКРЕТНОЙ функции обрезается всё, что стоит справа от переменной, которой присвоено значение этой самой функции... С конкатенацией-то я разобрался, а вот в чём тут проблема - понять не могу... :(

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя Alec
Alec(11 лет 9 месяцев)

Дело наверно в кодировке. Попробуй UTF-8 вместо default.

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Пробовал. Дело, как мне кажется, на 99% не в кодировке - как я написал, при работе с файлами, т.е. тогда, когда я не пытаюсь соединять строки, всё работает идеально, а когда я пытаюсь что-либо присвоить СПРАВА от строки, полученной с помощью описанной функции - всё идёт по... :((( Пробовал разные кодировки - содержимое строки меняется, А СПРАВА ОТ НЕЁ - всё обрезается как х... бритвой... :(

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя PigPog
PigPog(12 лет 9 месяцев)

Я бы использовал https://msdn.microsoft.com/ru-ru/library/ms128028(v=vs.110).aspx

FileSystem.ReadAllText (String)

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Да, но мне нужно считать файл именно как binary - потому что содержимое файла может быть далеко не только текстовым...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя PigPog
PigPog(12 лет 9 месяцев)

https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/l...

Попробуйте эту функцию. То что вы используете не преобразует байты в строку.

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Дык :)) Я её и использую.

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя PigPog
PigPog(12 лет 9 месяцев)

System.Text.Encoding.Default.GetBytes(FileContent).    вот это вы используете

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Ниже написал. GetString для преобразования массива в строку.

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя GaussCurve
GaussCurve(11 лет 4 месяца)

encoding.default.GetString(FileContent)

Аватар пользователя iStalker
iStalker(12 лет 9 месяцев)

Я не программист, но подобные задачи решается по-другому, вообще без кода.

Если файл содержит строки, каждая из которых должна попасть в строку таблицы БД, то берете ексель, открываете файл, пишете в свободном столбце формулу "UPDATE TABLE ..." & An, а потом выполняете полученные запросы в СУБД.

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

У меня задача - запихать файл (любой) в поле таблицы. Соответственно, в таблице есть поле типа varbinary, и программа должна читать файл в двоичном виде. Как-то так.

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя kue
kue(10 лет 5 месяцев)

Лет пять назад я подобное в потоке открывал-отправлял, но не в васике, конечно )

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Народ, я прошу прощения, я опубликую кусок кода:

SourceFileName = "D:\BD\SQLDB\texttrying\source.doc" - определяю имя файла для чтения

FileContent = My.Computer.FileSystem.ReadAllBytes(SourceFileName) - читаю файл в массив в бинарном виде

FileContentString = System.Text.Encoding.Default.GetString(FileContent) - преобразую массив байтов в строку

далее пытаюсь работать с переменной FileContentString - и возникает описанная ситуация. Всё, что правее её в конкатенации - наглухо режется (не понимаю, чем и почему). Простите, люди, сам запутался, и вас запутал :(

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя abyss
abyss(12 лет 9 месяцев)

Строка это строка, а бинарные данные это бинарные данные и их в строку смысла нет переводить, ведь как только встретится ноль, то строка обрежется (зависит от языка).

Более того, мешанину из непечатных символов не имеет смысла в базу пихать.

У вас проблема с постановкой задачи, она неверная, так не делают.

Скажите что конкретно вы хотите достичь.

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Хочу (нужно) запихать содержимое файла (конкретно - рабочей программы, как правило, это файлы word) и хранить в базе MS sql server. Для этого я создал таблицу на сервере с полями типа varbinary и пытаюсь файлы читать и передавать на сервер. И извлекать из таблицы без потерь форматирования. И всё бы получилось (независимо от того, правильно или неправильно я действую,) если бы не возникла описанная в тексте статьи проблема...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя Er0p
Er0p(9 лет 7 месяцев)

кроме ноля может встретиться символ конца файла. но мне кажется в запрос Вы не сможете впихнуть файл произвольной длины (даже если перевести его в 16-ричный вид), т.к. длина запроса ограничена, SQL запросто обрежет команду на 4-8 кб текста. У поля типа бинари должен быть соответствующий метод чтения данных из файла, вот им и пользуйтесь.
 

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Да ничего подобного. Я пробовал раньше текст из буфера обмена присваивать в переменную - всё получалось. в SQL Server всё тоже передавалось без проблем - независимо от длины текста. При использовании описанных функций, если ничего не пробовать прибавлять к переменным, содержимое этих переменных прекрасно передаётся из файла в файл - а вот при попытке конкатенации СПРАВА всё режется. Тоже пробовал на файлах разного размера и типа. Так что мутно всё...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя abyss
abyss(12 лет 9 месяцев)

ничего бы и не получилось.

с банарными данными надо и работать как с бинарными данными.

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

никогда не заталкивал файлы и не уверен как это делается, возможно нужет тип данных 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

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Всё это я прошёл. Openrowset не умеет считывать данные из ПРОИЗВОЛЬНЫХ файлов - у меня не получилось. По-моему, корректно он читает ТОЛЬКО текстовые файлы. Именно поэтому чтение и представление того, что передаётся в запрос, пытаюсь возложить на приложение. BLOB - это и есть varbinary (max) в терминологии SQL SERVER... Именно поэтому я читаю содержимое файла как binary, именно поэтому всякие преобразования использую. Вопрос в другом - почему ИМЕННО эта функция как будто обрезает любые выражения, что написаны СПРАВА от переменной, полученной при использовании этой самой функции. Это очень странно.Про хранение ФАЙЛОВ в БД - это отдельный вопрос. В любом случае, сейчас мне без этого не обойтись.

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя abyss
abyss(12 лет 9 месяцев)

но ваш способ тоже работать не будет, даже есть вы запихаете, то восстановить скорее не сможете, потому что преобразование обычно НЕобратимо.

например, строка обрезается как только встретился ноль ибо это код окончания строки.

кстати, бинарные данные в виде строки можно сохранить, но в кодированом виде, например используя BASE64, вот тогда проблем, кроме размера, не будет.

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Спасибо. Я в конце концов всё равно разберусь :) Но вот этот случай меня просто из себя вывел - я просто НЕ МОГУ ПОНЯТЬ, ЧТО ИДЁТ НЕ ТАК :))) Насчёт нулей как окончание строки - сейчас, как я понял, есть методы, которые считывают файл ЦЕЛИКОМ, так что этого, наверное, можно не опасаться... Но вот, как выясняется, у них есть свои...хм... ЗАМОРОЧКИ... :)) А бинарные данные в базу я уже пихал. работает. Только вот форматирование текста теряется при преобразовании из varbinary в varchar - это я и пытаюсь обойти...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя abyss
abyss(12 лет 9 месяцев)

вы просто неправильно используете, потому и лезут проблемы.

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

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Хм. Интересно. А что с этим сделать можно? Интерпретатор(?) ЛЮБОЙ 0 воспринимает как окончание команды? Как использовать BASE64 - я просто не знаю... Буду благодарен, если подскажете...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя abyss
abyss(12 лет 9 месяцев)

я VB не знаю и исхожу из того, что работает аналогично C++

соответсвено как прикрутить BASE64 не подскажу, но гугл подсказывает:

https://msdn.microsoft.com/en-us/library/dhx0d524(v=vs.110).aspx

важно именно бинарные данные подавать, а не вашу строку.

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Я не знаю, конечно, содержимого этой строки, но, т.к. она формируется на основе именно бинарных данных (строка получается преобразованием БИНАРНОГО массива в СТРОКУ(?) - наверное, бинарную), то логично предположить , что строка - представляет собой бинарные данные. За подсказку - спасибо огромное :)

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя abyss
abyss(12 лет 9 месяцев)

я имел в виду, что в строку преобразовывать не надо, т.е. этот вызов не только не нужен, но и вреден: System.Text.Encoding.Default.GetString

в Base64 БИНАРНЫЕ данные передаются, строки тоже можно, но это в редких случаях

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Спасибо за подсказку. Всё оказалось проще, чем казалось. :) Кстати, насчёт OPENROWSET я был неправ - всё он умеет считывать, это просто я неправильно извлекал. Что поделаешь, не программист, а учиться на ходу - непросто...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя Podvalny
Podvalny(10 лет 8 месяцев)

именно так. BASE64 encoding - и никаких бинарных нулей, спецсимволов и прочей дряни, чистый ASCII, как слеза комсомолки. 

Скрытый комментарий Повелитель Ботов (без обсуждения)
Аватар пользователя Повелитель Ботов
Повелитель Ботов(54 года 11 месяцев)

Перспективный чат детектед! Сим повелеваю - внести запись в реестр самых обсуждаемых за последние 4 часа.

Комментарий администрации:  
*** Это легальный, годный бот ***
Аватар пользователя pio
pio(8 лет 8 месяцев)

Может посмотреть что получилось msgbox(string) после импорта из двоичного файла?

Комментарий администрации:  
*** отключен (засорение эфира) ***
Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

попробую

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Вот такая вот фигня...

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя bron147
bron147(12 лет 10 месяцев)

Не знаю конечно что за базу вы используете, но MSSQL и ORALE имеют тип blob  - его использование самое простое решение в вашем случае (если ваша СУБД поддерживает этот тип). В Basic работа с этим типом осуществляется через ado.stream (если мне память не изменяет).

По вашей проблеме подсказать конкретно  в чем проблема - невозможно. Необходим полный текст ваших процедур, какая база, тип поля куда пихаете данные и т.д., 

Навскидку - обрезание массивов (права, слева или вообще) - говорит о том, что вы некорректно с ними работаете. К примеру -  некорректно выделяете под него память, если он динамический.

И т.д.

 

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Могу скинуть на почту весь проект.

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя bron147
bron147(12 лет 10 месяцев)

кидайте.

завтра посмотрю чем можно помочь

Сделаю наверное проще. Завтра до обеда я вам скину действующий пример записи файла в базу (в поле blob).

Правда пример будет на связке Паскаль - Oracle. 

 

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

А... куда кидать-то? :).....

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя bron147
bron147(12 лет 10 месяцев)

кинул мыло в личку

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Ответил. Спасибо.

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Я разберусь. Спасибо огромное. Если что - кидайте код прямо в личку. Спасибо! :)

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя И-23
И-23(9 лет 2 месяца)

Вижуалвасик не знаю и знать не хочу.
Но знаю, что как минимум у Оракла есть… скажем так «особенности» в процедуре записи в базу бинарного объекта (простой INSERT/UPDATE не прокатывает).
Ну и с учётом взаимоотношений майкросовта с ораклом, в случае использования вижуалвасика может получиться… интересно.

Аватар пользователя alterlex
alterlex(10 лет 7 месяцев)

Но знаю, что как минимум у Оракла есть… скажем так «особенности» в процедуре записи в базу бинарного объекта (простой INSERT/UPDATE не прокатывает).

Это и у MS SQL так. Иначе и париться не имело бы смысла - select - и всё :)

Комментарий администрации:  
*** Отчислен (словоблудие, оранжизм) ***
Аватар пользователя bron147
bron147(12 лет 10 месяцев)

Простой insert/update там действительно не прокатит, однако ничего сверхсложного там нет

Страницы