Distribuir archivos desde el disco duro de 4D Server
Uno de los requisitos habituales en aplicaciones multi-usuarios es la necesidad de almacenar y consultar imágenes en alta definición o archivos pesados, desde cualquier punto de la red.
Gracias a los campos Blob podemos perfectamente almacenar este tipo de archivos en la base y dejar que 4D Server las distribuya. Otra opción interesante es guardar esas imágenes como archivos físicos en el disco duro del servidor, lo que facilita su manipulación, y permite conservar un archivo de datos 4D más reducido. Sólo conservamos en el registro 4D la ruta del archivo original y una miniatura de la imagen con el fin de previsualizarla fácilmente antes de descargarla a 4D Client.
Para subir las imágenes, por supuesto la forma más sencilla sería compartir en la red la carpeta de destino del servidor entre los usuarios, pero en realidad ¡no es obligatorio! Por motivo de seguridad, para añadir un control sobre los datos a subir o también porque la tecnología 4D no exige ningún sistema Servidor ni compartir volúmenes físicos, es perfectamente posible realizar esta tarea desde 4D Client.
Subir una imagen a 4D Server
Empezamos por crear un método que se encargue de localizar la imagen en la máquina cliente.

El método del botón Cargar Imagen es el siguiente:
`Método Cargar_Imagen
C_INTEGER($Platform;$Pos)
C_STRING(1;$Separador)
C_BLOB($vblobArchivo)
$vhDocRef:=Open document(”") ` Selecciona la imagen
If (OK=1) `
CLOSE DOCUMENT($vhDocRef)
DOCUMENT TO BLOB(Document;$vblobArchivo)
$Path:=Direccion (Document;”")
$proc:=Execute on server (”Subir_Imagen”;1024*32;”Subir_Imagen”;$vblobArchivo;$Path)
SET BLOB SIZE($vblobArchivo;0)
CLOSE DOCUMENT($vhDocRef)
DOCUMENT TO BLOB(Document;$vblobArchivo)
$Path:=Direccion (Document;”")
$proc:=Execute on server (”Subir_Imagen”;1024*32;”Subir_Imagen”;$vblobArchivo;$Path)
SET BLOB SIZE($vblobArchivo;0)
End if
Este método ejecuta un procedimiento almacenado en el servidor Subir_Imagen, que graba la imagen en la carpeta predefinida en el método On Server Startup, en este caso en una subcarpeta específica, al lado de la estructura de la base.
`Método Subir_Imagen
C_BLOB($1;$blobArchivo)
C_STRING(80;$path;$type;$2;$3)
C_PICTURE($Image)
$blobArchivo:=$1
$nombre:=$2
$vhDocRef:=Create document(<>Path+$nombre)
If (OK=1) ` Si el documento fue creado
CLOSE DOCUMENT($vhDocRef)
BLOB TO DOCUMENT(Document;$blobArchivo)
BLOB TO PICTURE($blobArchivo;$Image)
CREATE THUMBNAIL($Image;$Image;48;48;Scaled to Fit ;0) `Se crea la vista en miniatura
CREATE RECORD([Imagenes]) `Se crea el registro con el path y la vista en miniatura
[Imagenes]Id:=Sequence number([Imagenes])
[Imagenes]Path:=”Imagenes”+<>separador+$nombre
[Imagenes]Vista_Miniatura:=$Image
SAVE RECORD([Imagenes])
CLOSE DOCUMENT($vhDocRef)
BLOB TO DOCUMENT(Document;$blobArchivo)
BLOB TO PICTURE($blobArchivo;$Image)
CREATE THUMBNAIL($Image;$Image;48;48;Scaled to Fit ;0) `Se crea la vista en miniatura
CREATE RECORD([Imagenes]) `Se crea el registro con el path y la vista en miniatura
[Imagenes]Id:=Sequence number([Imagenes])
[Imagenes]Path:=”Imagenes”+<>separador+$nombre
[Imagenes]Vista_Miniatura:=$Image
SAVE RECORD([Imagenes])
End if
SET BLOB SIZE($blobArchivo;0)
Subir_Imagen crea también un registro en la Tabla [Imagenes] que almacena el path y una vista en miniatura de la imagen, lógicamente esta vista en miniatura es mucho menos pesada que el tamaño del archivo original, y por lo tanto no afectará notablemente al archivo de datos.

Visualizar la imagen desde (otro) 4D Client
Para visualizar la imagen en su tamaño normal se debe enviar al servidor la petición para que éste busque dentro del Disco Duro central la imagen y la retorne en un Blob al Cliente que la solicitó. Esta petición se envía desde el formulario detallado en el mismo momento en que se carga.
`Método del Formulario de Entrada
C_BLOB($vblobArchivo)
C_PICTURE(ImgTamañoOriginal)
Case of
: (Form event=On Load )
$proc:=Execute on server (”Cargar_Imagen_Servidor”;1024*32;”Cargar_Imagen_ Servidor”;
¬ [Imagenes]Id)
GET PROCESS VARIABLE($proc;vblobArchivo;$vblobArchivo)
BLOB TO PICTURE($vblobArchivo;ImgTamañoOriginal)
PICTURE PROPERTIES(ImgTamañoOriginal;imgW;imgH)
: (Form event=On Load )
$proc:=Execute on server (”Cargar_Imagen_Servidor”;1024*32;”Cargar_Imagen_ Servidor”;
¬ [Imagenes]Id)
GET PROCESS VARIABLE($proc;vblobArchivo;$vblobArchivo)
BLOB TO PICTURE($vblobArchivo;ImgTamañoOriginal)
PICTURE PROPERTIES(ImgTamañoOriginal;imgW;imgH)
End case
El anterior método ejecuta en el servidor el procedimiento almacenado Cargar_Imagen_Servidor que permite seleccionar y cargar en una variable de tipo Blob la imagen residente en el Disco Duro.
`Mètodo Cargar_Imagen_Servidor
C_LONGINT($1;$ID)
C_BLOB(vblobArchivo)
$ID:=$1
QUERY([Imagenes];[Imagenes]Id=$ID)
$vhDocRef:=Open document(<>Separador+[Imagenes]Path)
If (OK=1)
CLOSE DOCUMENT($vhDocRef)
DOCUMENT TO BLOB(document;vblobArchivo)
DELAY PROCESS(Current process;300) `Se genera un retardo para poder leer las variables desde el cliente
CLOSE DOCUMENT($vhDocRef)
DOCUMENT TO BLOB(document;vblobArchivo)
DELAY PROCESS(Current process;300) `Se genera un retardo para poder leer las variables desde el cliente
End if
El formulario de detalle se abre con la imagen en alta definición, desde cualquier punto de la red, Mac o Windows, sin necesidad de tener un acceso de red al archivo físico.

Una base de ejemplo con el código fuente descrito más arriba está libremente disponible aquí (7 Mb)
Publicado el 5 Septiembre, 2007 por redaccion | | Imprime este artículo
23 Septiembre, 2007 a las 3:32 am
Hola, he querido implementar el codigo en mi BD pero en lugar de imagenes quiero usar documentos y abrirlos en el cliente pero noe ncuentro como abrir una aplicacion externa (pdf, excel, etc) a partir de que estar guardado en server.
4D Server 10.4.6
Mac OS 10.4
Saludos,