Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Caché Новый топик    Ответить
 Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
u78
Member

Откуда: Москва
Сообщений: 534
Property MyStream As %Stream.GlobalBinary;

/// Write ##class(FCE.Webtest).FillStream()
ClassMethod 
FillStream( FileName As %String "C:\InterSystems\Image.jpg")
{
    
Set Obj = ..%New()

    
Set FileObj ##class(%File).%New(FileName)
    
ok FileObj.Open("RS")
    
    
Write "File size = "_FileObj.Size,!
    
    
ok Obj.MyStream.CopyFrom(FileObj)
    
If $$$ISERR(okQuit "CopyFrom "_$system.Status.GetErrorText(ok)
    
    
Write "MyStream.Size = "_Obj.MyStream.Size_$Char(13,10)
    
    
Set ok Obj.%Save()
    
If $$$ISERR(okQuit "%Save "_$system.Status.GetErrorText(ok)
    
Quit $$$OK
}
Выдаёт ошибку:

CopyFrom ОШИБКА #5002: Ошибка: <TRANSLATE>zRead+7^%Library.File.1

Я ведь открываю его как stream, свойство MyStream - BinaryStream, при чём тут таблица трансляции???

Кто нибудь знает как загрузить локальный файл в базу? Это вообще возможно в Cache?
22 ноя 16, 22:00    [19922864]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
П.С.М.
Member

Откуда: Из СССР
Сообщений: 373
u78,

А если так?
ClassMethod FillStream(FileName As %String "C:\InterSystems\Image.jpg")
{
    
Set Obj = ..%New()

    
//Set FileObj = ##class(%File).%New(FileName)
    //s ok = FileObj.Open("RS")
    
    
Set FileObj=##class(%Stream.FileBinary).%New()
    
Set FileObj.Filename=FileName
    
    
Write "File size = "_FileObj.Size,!
    
    
ok Obj.MyStream.CopyFrom(FileObj)
    
If $$$ISERR(okQuit "CopyFrom "_$system.Status.GetErrorText(ok)
    
    
Write "MyStream.Size = "_Obj.MyStream.Size_$Char(13,10)
    
    
Set ok Obj.%Save()
    
If $$$ISERR(okQuit "%Save "_$system.Status.GetErrorText(ok)
    
Quit $$$OK
}
23 ноя 16, 00:21    [19923223]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
krvsa
Member

Откуда: г Волжский
Сообщений: 12794
u78
Кто нибудь знает как загрузить локальный файл в базу? Это вообще возможно в Cache?
Используем такой вариант...
  /// Прочитать бинарный файл в глобал
  /// [Параметры]
  /// File* - Путь и имя файла
  /// Name* - Имя глобала
  /// Len - Количество символов в строке
binLoad(File,Name,Len)
  
len,of
  
s:$g(Len)="" Len=200
  
len=0
  
of=##class(%FileBinaryStream).%New()
  
of.Filename=File
  
@Name
  
f  d BINPART q:of.AtEnd
  k 
of
  
q:$q len
  
q
BINPART ; Очередная часть файла
  
str
  
str=of.Read(Len)
  
@Name@($i(@Name))=str
  
i $i(len,$l(str))
  
q
23 ноя 16, 10:02    [19923683]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
u78
Я ведь открываю его как stream, свойство MyStream - BinaryStream, при чём тут таблица трансляции???
При том, что Вы его не открываете как поток: "S" (/STREAM) - в данном случае это нечто другое.
Правильно так:
ok FileObj.Open(##class(%FileStreamAdaptor).#OPENREAD)
что равносильно
ok FileObj.Open("RUK\RAW\")
Чтобы обезопасить себя от ошибок, лучше - как правильно заметил П.С.М. - использовать соответствующие классы, а не универсальный %File.

PS: если Вы возвращаете строку, то строку, если статус - то статус. Смешивать два разных возвращаемых типа в одном методе - ошибка.
ClassMethod FillStream( FileName As %String "C:\InterSystems\Image.jpg"As %String or %Status?
23 ноя 16, 10:20    [19923752]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
u78
Member

Откуда: Москва
Сообщений: 534
Да, надо юзать %Stream.FileBinary а не %File
Спасибо коллеги
23 ноя 16, 10:53    [19923929]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
krvsa
Используем такой вариант...
Чем он лучше стандартных средств?
binLoad(File,Name) public {
  
of=##class(%Stream.FileBinary).%New(), of.Filename=File
  
t=##class(%Stream.GlobalBinary).%New(Name)
  
t.CopyFromAndSave(of)
  
t.Id
}
23 ноя 16, 10:54    [19923932]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
u78
Member

Откуда: Москва
Сообщений: 534
servit,

Вы неправы. В оригинальном примере я открываю его именно как поток.
Вот документация %Library.File метод Open():
автор
mode is a string containing one or more file modes including:
R Read
W Write
S Stream mode
N Create a new file (overwrite existing file)


насчёт типов возврата вы можете поумничать в отдельном посте, спасибо
23 ноя 16, 10:58    [19923949]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
krvsa
Member

Откуда: г Волжский
Сообщений: 12794
servit
Чем он лучше стандартных средств?

В свое время так же искали вариант "бинарного" чтения файлов... Насоветовали в то время такой вариант.
Кто именно насоветовал уже никто не помнит.
23 ноя 16, 11:27    [19924121]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
u78,

Если файл локальный и/или он довольно большой, то можно хранить в БД не сам файл, а только ссылку на него, например так:
Property MyStream As %Stream.FileBinary;

/// d $system.OBJ.DisplayError(##class(FCE.Webtest).FillStream())
ClassMethod 
FillStream(FileName As %String "C:\InterSystems\Image.jpg"As %Status
{
  
#dim ex As %Exception.AbstractException
  
res $s(##class(%File).Exists(FileName):$$$OK,1:$$$ERROR($$$FileDoesNotExist,FileName))
  
try {
    
$$$ThrowOnError(res)
    
    
Obj = ..%New()
    
    
$$$ThrowOnError(Obj.MyStream.LinkToFile(FileName))
    
    
"MyStream.Size = "_Obj.MyStream.Size_$$$NL
    
    $$$ThrowOnError
(Obj.%Save())
  
}catch(ex{
    
res ex.AsStatus()
  
}
  
res
}
23 ноя 16, 11:35    [19924190]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
П.С.М.
Member

Откуда: Из СССР
Сообщений: 373
servit уже приводил ссылку, что такое S:

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GIOD_rmsseqfiles#GIOD_rmsseq_openparamstbl
S /STREAM Stream format with carriage return, line feed, or form feed as default terminators. Jobbed processes that inherit TCP devices are automatically set to “S” format. You can reset the format with the USE command. S, V, F, and U modes are mutually exclusive. Stream record format is the default on non-OpenVMS systems. Variable length (V) is the default on OpenVMS systems.
23 ноя 16, 11:40    [19924218]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
krvsa,

То, что это legacy-код - понятно, непонятно зачем его использовать сегодня при наличии готовых средств?
Как минимум, в нём можно увеличить размер блока при чтении файла с 200 байт до 32767 или даже 3641144. Точнее можно определить по $zutil(96,39). Это значительно ускорит чтение файла.
23 ноя 16, 11:46    [19924264]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
krvsa
Member

Откуда: г Волжский
Сообщений: 12794
servit
непонятно зачем его использовать сегодня при наличии готовых средств?

Дело в том, что у нас два "комплекта" "системных" программ, для Каше и для ГТ.М...
Меняя комплект получаем ПО для нужной СУБД... "Прикладные" программы работают только через "системные" процедуры и функции...
Т.о. нет разницы в какой СУБД импортировали файл, глобал получится как нужно и нужными "порциями".

Да и зачем менять что-то, если оно работает и не создает проблем?
23 ноя 16, 13:26    [19924855]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
u78
Вы неправы. В оригинальном примере я открываю его именно как поток.
Вот документация %Library.File метод Open():
Что такое "stream mode" выше уже процитировал П.С.М.. Этот режим никоим образом не означает, что Вы работаете именно с двоичным потоком.
Это легко проверить:
ClassMethod FillStream(
  
FileName As %String = {$$GetFilename^%apiCSP("/csp/samples/ClassLogo.jpg")},
  
Mode As %String "RUK\RAW\")
{
  
#dim ex As %Exception.AbstractException
  
res $s(##class(%File).Exists(FileName):$$$OK,1:$$$ERROR($$$FileDoesNotExist,FileName))
  
try {
    
$$$ThrowOnError(res)
    
    
of=##class(%File).%New(FileName)
    
$$$ThrowOnError(of.Open(Mode))
    
s="" ; читаем сюда содержимое файла
    
while 'of.AtEnd {
      
s=s_of.Read()
    
}
    
of.Close()
    
    
of.Size,$s(of.Size=$l(s):"=",1:"≠"),$l(s),!
    
  
}catch(ex{
    
!,ex.DisplayString(),!
  
}
}
Результаты:

USER>##class(FCE.Webtest).FillStream(,"R")
2077≠1491

USER>##class(FCE.Webtest).FillStream(,"RS")
2077≠1491

USER>##class(FCE.Webtest).FillStream(,"RU")
2077≠1538

USER>##class(FCE.Webtest).FillStream(,"RSK\RAW\")
2077≠2053

USER>##class(FCE.Webtest).FillStream(,"RUK\RAW\")
2077=2077

Цифры отличаются, поскольку это зависит ещё и от настроек локали: Default I/O Tables
У меня это локаль rusw, где для файлов по умолчанию используется таблица UTF8, что для бинарных файлов не подходит от слова совсем.
23 ноя 16, 13:40    [19924933]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
krvsa
Да и зачем менять что-то, если оно работает и не создает проблем?
Между хорошим и лучшим существует разница.
23 ноя 16, 13:48    [19924970]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
krvsa
Member

Откуда: г Волжский
Сообщений: 12794
servit
Между хорошим и лучшим существует разница.

А еще поговаривают, что лучшее - враг хорошего.
23 ноя 16, 14:33    [19925195]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
krvsa
А еще поговаривают, что лучшее - враг хорошего.
Без тестирования - безусловно.
23 ноя 16, 14:36    [19925217]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
krvsa
Member

Откуда: г Волжский
Сообщений: 12794
servit, у нас есть клиенты со старинными версиями... Т.ч. не все новое и передовое у них вообще есть.
23 ноя 16, 16:41    [19926150]     Ответить | Цитировать Сообщить модератору
 Re: Чтение бинарного файла вызывает ошибку TRANSLATE, как сохранить локальный файл в базе ?  [new]
servit
Member

Откуда: г. Кишинёв, Республика Молдова
Сообщений: 3070
Блог
krvsa
у нас есть клиенты со старинными версиями... Т.ч. не все новое и передовое у них вообще есть.
Если есть %FileBinaryStream, значит должен быть и %GlobalBinaryStream, который есть даже в 5.0.x:
 of=##class(%FileBinaryStream).%New()
 
of.Filename=File
 
t=##class(%GlobalBinaryStream).%New(Name)
 
t.CopyFromAndSave(of)
23 ноя 16, 18:10    [19926559]     Ответить | Цитировать Сообщить модератору
Все форумы / Caché Ответить