style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Problemas con el formato de un path

Hola... disculpen, tengo un problema con un path que parece ser básico pero ya tengo varias horas luchando con eso y no me sale.

Quiero poder descargar un archivo del servidor con el siguiente código.

  public void cbDescargar() throws IOException {
   
  // String strPath = "..//..//archivos";
 
    String file = "Sample.csv";
   
        String strPathCSV;
        strPathCSV = file; //strPath + file;
   
        File ficheroCSV = new File(strPathCSV);

       System.out.printf(ficheroCSV.getAbsolutePath());

    FacesContext ctx = FacesContext.getCurrentInstance();
   
    FileInputStream fis = new FileInputStream("../../archivos/" + ficheroCSV);

   
    byte[] bytes = new byte[1000];
    int read = 0;

    if (!ctx.getResponseComplete()) {
       String fileName = ficheroCSV.getName();
       String contentType = "application/vnd.ms-excel";
       //String contentType = "application/pdf";
       HttpServletResponse response =(HttpServletResponse) ctx.getExternalContext().getResponse();
       
       response.setContentType(contentType);
       response.setHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");
       ServletOutputStream out = response.getOutputStream();

       while ((read = fis.read(bytes)) != -1) {
            out.write(bytes, 0, read);
       }

       out.flush();
       out.close();
       System.out.println("\nDescargado\n");
       ctx.responseComplete();
    }
  }

Cuando lo pruebo en mi PC funciona perfectamente, pero cuando lo subo al server siempre me marca que no puede encontrar el path especificado.

¿Qué formato tiene que tener para que lo encuentre en el server?

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

path absoluto

desde el principio debes marcar un path absoluto. En la PC te funciona cuando corres el programa en el directorio donde está la clase y el archivo, pero si lo corres desde otro lado ya no funcionará.

Otra opción que considero mejor es que si el archivo lo tienes en algun directorio de tu classpath, puedes usar getClass().getResourceAsStream() para obtener ya un InputStream hacia tu archivo, el cual lees y luego cierras.

Imagen de xalCho

¿?¿?

Eso suena muy fácil, pero la verdad no tengo idea de lo que estás hablando :(, uso getClass().getResourceAsStream() en vez de FileInputStream("../../archivos/" + ficheroCSV) ?

Imagen de ezamudio

getResourceAsStream()

Sí. Cuando usas FileInputStream tienes que pasarle la ruta absoluta, porque si le pasas una ruta relativa puede que no te encuentre el archivo si el directorio actual no es el que esperabas.
Si el archivo que quieres leer está en el classpath, puedes usar getClass().getResourceAsStream(ficheroCSV) con el puro nombre del archivo (o ponerle "/" al principio) y ese método te devuelve un InputStream ya abierto para leer el contenido del archivo.

Imagen de xalCho

Gracias de todas formas

Me temo ezamudio que soy más torpe de lo que creí, no pude hacerlo, antes me marcaba que no encontraba el path, ahora me marca error de puntero nulo. Creo que mejor le voy a pasar a alguien más ese módulo. Estaba tan cerca y no quedó. Y es que estoy tan lejos de entenderte, no conozco esas funciones que me dices y no se como usarlas.

Gracias de todas maneras. Un saludo

Imagen de JaimeItlzc

Por que

Por que no pones un Screenshot o algo de Codigo donde lo estes haciendo tal vez eso te podria ayudar a que te guien aun mejor.

Saludos.

Properties

Si la ubicacion del fichero es constante escribelo en un archivo properties donde podras poner

    myPath=C:/a/b/c/

y despues obtienes esa direccion en una variable y cuando quieras leer el archivo concatenas la direccion de tu "myPath" con el nombre del archivo que quieres leer

    FileInputStream fis = new FileInputStream(myPath + ficheroCSV);

para evitarte el properties lo puedes poner como codigo duro (para fines de pruebas, nunca es recomendado hacer codigo duro).

Imagen de CybJer

La pregunta obligada

¿Realmente el archivo esta 2 directorios arriba del que se encuentra tu clase en una carpeta llamada archivos?
Esa es la estructura de directorios que deberia tener tu servidor para que funcione el codigo que presentas (por lo menos eso sugiere)

----dir1
---------/archivos
---------------------/Sample.csv
---------/dir2
---------------/dir3
---------------------/tuClase.class

y porque no intentas poner el path absoluto de tu archivo (para probar)
FileInputStream fis = new FileInputStream("c:/dir1/archivos" + ficheroCSV);
o
FileInputStream fis = new FileInputStream("/dir1/archivos" + ficheroCSV);
segun corresponda
PD: Hay que evitar en la medida de lo posible poner el path en duro

Imagen de Ehumir

Déjame ver ...

A ver si entendí el problema, ¿tu código funciona sólo cuando buscas un archivo en tu PC no? es decir usas un path como "C:/.../.../archivos/", pero cuando quieres encontrar el archivo en el server te dice que no lo encuentra.

¿Ese es el problema? te lo digo porque veo que todos (menos @ezamudio ) te están ofreciendo solución para algo que entiendo que ya hace tu código o me equivoco.

Imagen de xalCho

Re: Déjame ver ...

Exacto, he probado mi código cientos, miles de veces y cuando escribo el path el "C:\\..\..\archivos\" funciona perfectamente. pero cuando el archivo que quiero descargar esta en el servidor SIEMPRE me dice que no encuentra el archivo. me dice " no se pudo encontrar el path ../../archivos/sample.csv " y ya he escrito de miles de formas el path y no lo encuentra.

Me he roto la cabeza pensando qué es lo que me dijo ezamudio, porque tengo la corazonada que por ahí va el asunto, pero simplemente no ha funcionado. Se ve tan fácil, sin embargo a varias personas con las que he consultado no ha podido resolver el problema, todos se limitan a decir "haz un path como c.\\..\..\ y luego concatenas" pero eso ya lo hace mi código perfectamente.

El problema es EN EL SERVER (no es un grito, solo es para que no quede duda).

Según lo que le entendí a ezamudio tenía que hacer algo muy sencillo y lo que hice fue lo sig.

En la página jspx añadí un botón que tiene como principal acción y al archivo .java de la pantalla y buscar la función cbDescargar, cuyo código es el que sigue.

public String cbDescargar() throws IOException {

    String file = "Sample.csv";
   
    FacesContext ctx = FacesContext.getCurrentInstance();
   
    InputStream fis = getClass().getResourceAsStream(file);
   
   
    byte[] bytes = new byte[1000];
    int read = 0;

    if (!ctx.getResponseComplete()) {
       String fileName = file;
       String contentType = "application/vnd.ms-excel";
       HttpServletResponse response =(HttpServletResponse) ctx.getExternalContext().getResponse();
       response.setContentType(contentType);
       response.setHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");
       ServletOutputStream out = response.getOutputStream();

       while ((read = fis.read(bytes)) != -1) {
            out.write(bytes, 0, read);
       }

       out.flush();
       out.close();
       System.out.println("\nDescargado\n");
       ctx.responseComplete();
    }

   
    return null;
   

Pero esto tiene menos funcionalidad que un "hola mundo", ni siquiera imprime algo.

¿Donde se ubica tu archivo?

Hola primero que nada quisiera preguntarte ¿donde se ubica tu archivo, si se ubica en una carpeta de tu disco o se ubica en alguna carpeta de tu proyecto ?

por ejemplo si se ubica en algun directorio de tu disco lo que haces es correcto solo dale la ruta correcta mas si se encunetra en tu proyecto tendrias que hacer lo siguiente

FacesContext context = FacesContext.getCurrentInstance();
ServletContext request = (ServletContext) context.getExternalContext().getContext();
  ....  new File(request.getRealPath("/tu carpeta de proyecto /tu archivo");

con eso seria suficiente para que pueda acceder a tu archivo
y ya lo manipules para poder bajarlo

Espero que sea de ayuda

Saludos

Imagen de ezamudio

Sample.csv

Para que tu ejemplo de cbDescargar() funcione, el archivo Sample.csv necesita estar en alguno de los directorios del classpath. El más común sería el WEB-INF/classes dentro de tu aplicación.

Si tienes el Sample.csv en donde tienes tus jsp o jsf (al mismo nivel que WEB-INF por ejemplo) entonces:

InputStream fis = context.getExternalContext().getContext().getResource("/Sample.csv").openStream();
Imagen de xalCho

Error persistente...

Esto parece insolucionable...

public String cbDescargar() throws IOException {
 
    FacesContext ctx = FacesContext.getCurrentInstance();
    ServletContext request = (ServletContext) ctx.getExternalContext().getContext();
    File  file =  new File(request.getRealPath("../../archivos/Sample.csv"));
 
    FileInputStream fis = new FileInputStream(file);
    byte[] bytes = new byte[1000];
    int read = 0;

    if (!ctx.getResponseComplete()) {
       String fileName = file.getName();
       String contentType = "application/vnd.ms-excel";
       HttpServletResponse response =(HttpServletResponse) ctx.getExternalContext().getResponse();
       
       response.setContentType(contentType);
       response.setHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");
       ServletOutputStream out = response.getOutputStream();

       while ((read = fis.read(bytes)) != -1) {
            out.write(bytes, 0, read);
       }

       out.flush();
       out.close();
       System.out.println("\nDescargado\n");
       ctx.responseComplete();
    }
   return null;
}

y me devuelve :

avax.faces.el.EvaluationException: java.io.FileNotFoundException: C:\Documents and Settings\User\Application Data\JDeveloper\system11.1.1.3.37.56.60\o.j2ee\drs\SYS\ViewControllerWebApp.war\Sample.csv (The system cannot find the file specified)
at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:51)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent$1.run(ContextSwitchingComponent.java:90)
at oracle.adf.view.rich.component.fragment.ContextSwitchingComponent._processPhase(ContextSwitchingComponent.java:309)
.
.
.

pero aún lo sigue buscando en mi pc... yo quiero que lo busque en el WebLogic.

Te cometo, actualmente simplemente tengo un link en el jspx que me lleva al archivo "sample.csv" y si lo abre, pero lo hace en el explorer y yo lo que quiero es que lo descargue no que lo visualice.

Imagen de ezamudio

dos equipos?

Lo que yo había entendido es que si corres la aplicación en tu compu todo funciona bien pero si la corres en el server no funciona... pero todo esto considerando que existe una copia de Sample.csv tanto en tu compu como en el server. Obviamente las soluciones que te he propuesto requieren que pongas el Sample.csv dentro de tu aplicación, ya sea dentro de WEB-INF/classes o en WEB-INF o simplemente en el raíz del war.

Pero esto último que escribes "aún lo sigue buscando en mi pc... yo quiero que lo busque en el WebLogic"... me hace pensar que quieres que la aplicación encuentre el archivo en el server... cuando la app corre en tu compu?

Imagen de xalCho

Error persistente...

Ok, mejor explico todo:

Estoy hacendo una aplicación MVC en JDeveloper usando ADF faces+JSF+WebLogic... etc, estoy usando SVN con mi equipo de desarrollo, entonces entre los módulos que tengo que desarrollar hay un requerimiento que parece insignificante (pero que no he podido solucionar). El requerimiento es: "dar la opción de descargar el layout del cobro grupal", entonces como simplemente es descargar un archivo que se generó anteriormente pensé eso es pecata minuta, así que me enfoqué en crear hacer los métodos para crear el arch y otras cosas. Luego cuando ya atendí este requerimiento puse un link en la pantalla jspx que me lleve al archivo.

<a href="../../archivos/Sample.csv" target="_blank"
                     type="application/vnd.ms-excel">Descargar Layout</a>

Este link funciona bien, en efecto me liga al arch y lo descarga (me sale la ventana de Guardar como), entonces le di commit y listo, pero cuando hago un deploy para QA en las demás pcs el link abre el archivo en el explorador y no les sale la ventana de "guardar como". Entonces pensé que sería algo de la configuración de los explorer y por obvias razones no se puede quedar así, porque sin importar la configuración de sus explorer debe descargarse y no visualizarse. Seguidamente intenté más elaborado que un simple link.

<af:commandButton text="Descargar Layout"
                                    binding="#{backingBeanScope.backing_pages_cobranza_CobranzaFinancieraCG.cbDescargar}"
                                    id="cbDescargar"
                                    action="#{backingBeanScope.backing_pages_cobranza_CobranzaFinancieraCG.cbDescargar}"/>
public void cbDescargar() throws IOException {
   
  String strPath = "..//..//archivos";
 
  String file = "Sample.csv";
   
  String strPathCSV = /strPath + file;
   
  File archivoCSV = new File(strPathCSV);
   

    FacesContext ctx = FacesContext.getCurrentInstance();
   
    FileInputStream fis = new FileInputStream(archivoCSV);

   
    byte[] bytes = new byte[1000];
    int read = 0;

    if (!ctx.getResponseComplete()) {
       String fileName = archivoCSV.getName();
       String contentType = "application/vnd.ms-excel";
       //String contentType = "application/pdf";
       HttpServletResponse response =(HttpServletResponse) ctx.getExternalContext().getResponse();
       
       response.setContentType(contentType);
       response.setHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");
       ServletOutputStream out = response.getOutputStream();

       while ((read = fis.read(bytes)) != -1) {
            out.write(bytes, 0, read);
       }

       out.flush();
       out.close();
       System.out.println("\nDescargado\n");
       ctx.responseComplete();
    }
  }

y esto me devuelve un error que dice que no encuentra el path solicitado.

Entonces estuve haciendo pruebas y hasta hice una copia del archivo Sample.csv que está en la carpeta de mi proyecto a C:\ y cambié la instrucción

String strPath = "..//..//archivos";

por

String strPath = "c:\\";

y esto funciona perfectamente... pero desde luego que si le doy commit no va a funcionar, porque eso "descargar" la copia que está en mi pc y no la del proyecto.

Y en eso estoy atorado con ese requerimiento desde hace 3 semanas.

Yo digo que es simple pero no encuentro como hacer que se descargue el sample del proyecto sin tener que poner "C:\\..\\Proyecto\\publi_html\\archivos\\Sample.csv" porque además eso también solo va a funcionar en mi pc.

Espero se entienda mi explicación!

Imagen de xalCho

copie la carpeta /archivos

copie la carpeta /archivos al directorios /WEB-INF y puse el código así

   String strPath = "../../archivos/";
  String file = "Sample.csv";
 
  String strPathCSV = strPath + file;
  File archivoCSV = new File(strPathCSV);
  FacesContext ctx = FacesContext.getCurrentInstance();
   
  FileInputStream fis = new FileInputStream(archivoCSV);
   
   
    byte[] bytes = new byte[1000];
    int read = 0;

Cambié la parte inicial para ver si lo puedo encontrar en el claspath y me devuelve esto:

javax.faces.el.EvaluationException: java.io.FileNotFoundException: ..\..\archivos\Sample.csv (The system cannot find the path specified)
        at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:51)
        at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
        at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)
.
.
.
Imagen de Ehumir

Creo que tienes la

Creo que tienes la solución. Lo que todos queremos aquí no exactamente hacer tu trabajo, sino ayudarte a que puedas darte cuenta dónde está tu error y puedas corregirlo
, he leido con atención lo que explicas y siento que no estás explicando el verdadero problema que tienes, de hecho creo que no sabes bien cuál es.

Sacando en conclusión que lo único que te ocurre es que no sabes como leer el path de un archivo que pertenece a tu proyecto, puedo ofrecerte esta solución.

    public void cbDescargar() throws IOException {

        FacesContext ctx;
        ServletContext request;
        File archCSV;
        FileInputStream fisArch;
        byte[] bytes;
        int leer;
        String nombreArchivo;

        ctx = FacesContext.getCurrentInstance();
        request = (ServletContext)ctx.getExternalContext().getContext();
        archCSV = new File(request.getRealPath("/archivos/Sample.csv"));
        fisArch = new FileInputStream(archCSV);
        bytes = new byte[1000];
        leer = 0;

        if (!ctx.getResponseComplete()) {

            nombreArchivo = archCSV.getName();
            String contentType = "application/vnd.ms-excel";
            HttpServletResponse response =
                (HttpServletResponse)ctx.getExternalContext().getResponse();

            response.setContentType(contentType);
            response.setHeader("Content-Disposition",
                               "attachment;filename=\"" + nombreArchivo +
                               "\"");
            ServletOutputStream out = response.getOutputStream();

            while ((leer = fisArch.read(bytes)) != -1) {
                out.write(bytes, 0, leer);
            }

            out.flush();
            out.close();
            System.out.println("\nLayout descargado...\n");
            ctx.responseComplete();
        }

  }

Chécalo y dime si te funcionó.

Imagen de xalCho

Muchas gracias

@Ehumir me has salvado la vida, ya quedó.

Gracias a todos los que se interesaron en mi problema, pondré mas atención de ahora en adelante en los consejos e investigaré más para que no me tengan qe resolver el problema.

Saludos.

Imagen de Nopalin

Ojala

Realmente esperamos que así sea.
Una vez un usuario se quejó de que aqui se postean puras cosas básicas o simples, pero el problema no es quien las postea si no quien las contesta.

En fin, sobres

Descargar archivos del servidor

Hola presento el mismo problema al cual tu muy amablemente respondiste yo hago algo parecido pero no me da error y peor se abre un recuadro para ver si permite descargar el archivo mi codigo es:

package com.paco.beans;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

@ManagedBean
@SessionScoped
public class DownloadBean implements Serializable {

    private static final long serialVersionUID = 1L;

    public void cbDescargar() throws IOException {

        FacesContext ctx;
        ServletContext request;
        File archCSV;
        FileInputStream fisArch;
        byte[] bytes;
        int leer = 0;
        String nombreArchivo;

        ctx = FacesContext.getCurrentInstance();
        request = (ServletContext) ctx.getExternalContext().getContext();
        archCSV = new File(request.getRealPath("/reports/reporte.pdf"));
        fisArch = new FileInputStream(archCSV);
        bytes = new byte[1000];

        if (!ctx.getResponseComplete()) {

            nombreArchivo = archCSV.getName();
            String contentType = "application/pdf";
            HttpServletResponse response = (HttpServletResponse) ctx.getExternalContext().getResponse();

            response.setContentType(contentType);
            response.setHeader("Content-Disposition","attachment;filename=\"" + nombreArchivo + "\"");
            ServletOutputStream out = response.getOutputStream();

            System.out.println("leer " + leer);
            while ((leer = fisArch.read(bytes)) != -1) {
                out.write(bytes, 0, leer);
            }

            out.flush();
            out.close();
            System.out.println("\nDescargado...\n");
            ctx.responseComplete();
        }
    }

}

el archivo a descargar es un pdf

@registroya Mejor crea una

@registroya Mejor crea una entrada nueva e incluye un link a esta.

disculpa no te entendi mucho,

disculpa no te entendi mucho, yo lo que tengo en mi jsf es lo siguiente:

                <p:commandButton value="Bajar" action="#{downloadBean.cbDescargar}"/>

estoy utilizando primefaces

Que no escribas un comentario

Que no escribas un comentario extra en este post de hace 2 años. Mejor crea un nuevo post con tu duda.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">