2012-03-12 13 views
6

Estoy usando una clase CSVReader que toma un archivo local como entrada. Pero ahora, necesito poder leer los archivos locales y los que tienen una ruta URL (como http://example.com/example.txt). Para hacer esto, quiero derivar una clase de CSVReader que identifica si el archivo es local o URL, y luego pasar el InputStream al padre usando super() en la primera línea del constructor. ¿Cuál es la manera elegante de hacer esto?Solución cuando super no puede ser la primera línea del constructor en java

public class FileReader extends CsvReader{ 
    public FileReader(){ 
     if (fileName != null) { 

       if (fileName.trim().startsWith("http:")) { 
       // it is URL 
       URL url = new URL(fileName); 
       inputStream = new BufferedReader(new InputStreamReader(
         url.openStream(), charset), 
         StaticSettings.MAX_FILE_BUFFER_SIZE); 
       }else{ 
       //it is a local file 
       inputStream = new BufferedReader(new InputStreamReader(
         new FileInputStream(fileName), charset), 
         StaticSettings.MAX_FILE_BUFFER_SIZE); 
       } 

      } 
      //Now pass the input stream to CsvReader 
      super(inputStream, delimiter, charset); //error - super has to be first line of constructor 
    } 
} 
+0

Por favor, no llame a sus clases con los mismos nombres que las clases conocidas i n el JDK. Vas a causar una gran confusión a alguien, muy posiblemente a ti mismo. – EJP

Respuesta

11

Puede escribir métodos auxiliares:

super(createReader(createInputStream(resouce), "UTF-8"), ";"); 

Su método auxiliar podría tener este aspecto:

public static InputStream createInputStream(String resource) 
{ 
    resource = resource.trim(); 

    if (resource.startsWith("http:")) 
    { 
      return new URL(resource).openStream(); 
    } else 
    { 
      return new FileInputStream(new File(resource)); 
    } 
} 

public static BufferedReader createReader(InputStream is, String charset) 
{ 
    return new BufferedReader(new InputStreamReader(is, charset)); 
} 
+0

El método 'constructInputStream' debe declararse como' static'. –

+0

Es estático, excepto que el nombre es incorrecto. Voy a arreglar. –

+0

He agregado el comentario antes de la edición, sry. –

2

mover el código para calcular los argumentos a super() a una función estática, y lo llaman el interior super().

7

Puede declarar su constructor como private, y crear un método estático de fábrica, que hará la comprobación antes de invocar al constructor.

0

Puede refactorizar el código para incluir método estático que va a crear todo lo necesario y luego llamar el constructor:

public class FileReader extends CsvReader 
{ 
    public static FileReader createFileReader(String filename, String delimiter, String charset){ 
     if (fileName != null) { 
      BufferedReader inputStream; 
      if (fileName.trim().startsWith("http:")) { 
       // it is URL 
       URL url = new URL(fileName); 
       inputStream = new BufferedReader(new InputStreamReader(url.openStream(), charset), StaticSettings.MAX_FILE_BUFFER_SIZE); 
      } 
      else 
      { 
       //it is a local file 
       inputStream = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), charset), StaticSettings.MAX_FILE_BUFFER_SIZE); 
      } 
      return new FileReader(inputStream, delimiter, charset); 
     } 
     return null; 
    } 

    public FileReader(BufferedReader inputStream, String delimiter, String charset){ 
      super(inputStream, delimiter, charset); 
    } 
} 
Cuestiones relacionadas