Abrir archivo, leer datos y modificarlos en otro archivo.

Iniciado por Tonyskater, 22 Mayo 2017, 12:18 PM

0 Miembros y 1 Visitante están viendo este tema.

Tonyskater

Hola tengo una duda con un ejercicio que estoy haciendo de LeetSpeak, el enunciado es el siguiente:
a) Dado el siguiente archivo de texto traduce el LeetSpeak a letras.
b)Dado el siguiente archivo de texto traduce el siguiente texto a LeetSpeak

El archivo es una simple cadena de texto cualquiera.

Con la siguiente formula no deberia ser un problema traducirlos:

Lo cual en mi codigo es lo siguiente:
Código (java) [Seleccionar]
switch (LS) {
                    case 1:
                        while (input.hasNextLine()) {
                            frase = input.nextLine();
                            frase.replace('O', '0').replace('I', '1').replace('Z', '2').replace('E', '3').replace('A', '4')
                                    .replace('S', '5').replace('G', '6').replace('T', '7').replace('B', '8').replace('P', '9');
                            escribir(frase, 1);
                            System.out.println("Se ha formado el LeetSpeak");
                        }   break;
                    case 2:
                        while (input.hasNextLine()) {
                            frase = input.nextLine();
                            frase.replace('0', 'O').replace('1', 'I').replace('2', 'Z').replace('3', 'E').replace('4', 'A')
                                    .replace('5', 'S').replace('6', 'G').replace('7', 'T').replace('8', 'B').replace('9', 'P');
                            escribir(frase, 2);
                            System.out.println("Se ha traducido el LeetSpeak");
                        }   break;
                    default:
                        System.out.println("Introduce un valor valido.");
                        break;
                }

Esto funciona bien, ahora viene cuando explota mi cabeza...
En general este es mi
Código (java) [Seleccionar]
public class Escribir {

    public static void main(String[] args) {
        JFileChooser selector = new JFileChooser();
        selector.showOpenDialog(null);
        selector.setFileSelectionMode(JFileChooser.FILES_ONLY);
        if (selector.getSelectedFile() != null) {
            System.out.println("Has seleccionado el fichero: " + selector.getSelectedFile());
            File archivo = selector.getSelectedFile();
            try {
                FileReader entrada = new FileReader(archivo);
                BufferedReader BR = new BufferedReader(entrada);
                Scanner input = new Scanner(entrada);
                String frase = "";
                while (input.hasNextLine()) {
                    frase = input.nextLine();
                    System.out.println(frase);
                }
                //ESCRIBIR ✔✔
                int LS;
                System.out.println(
                        "¿Quieres un LeetSpeak de este archivo?[1] ");
                System.out.println(
                        "¿Quieres traducir este LeetSpeak?[2] ");
                System.out.print(
                        "Introduce opcion del menu [1|2]: ");
                Scanner menu = new Scanner(System.in);
                LS = menu.nextInt();
                switch (LS) {
                    case 1:
                        while (input.hasNextLine()) {
                            frase = input.nextLine();
                            frase.replace('O', '0').replace('I', '1').replace('Z', '2').replace('E', '3').replace('A', '4')
                                    .replace('S', '5').replace('G', '6').replace('T', '7').replace('B', '8').replace('P', '9');
                            escribir(frase, 1);
                            System.out.println("Se ha formado el LeetSpeak");
                        }   break;
                    case 2:
                        while (input.hasNextLine()) {
                            frase = input.nextLine();
                            frase.replace('0', 'O').replace('1', 'I').replace('2', 'Z').replace('3', 'E').replace('4', 'A')
                                    .replace('5', 'S').replace('6', 'G').replace('7', 'T').replace('8', 'B').replace('9', 'P');
                            escribir(frase, 2);
                            System.out.println("Se ha traducido el LeetSpeak");
                        }   break;
                    default:
                        System.out.println("Introduce un valor valido.");
                        break;
                }
                entrada.close();
            } catch (FileNotFoundException e) {
                System.out.println("Fichero no encontrado");
            } catch (NoSuchElementException e) {
                System.out.println("No es un formato correcto");
                System.out.println("Se esperaba un .txt");
            } catch (Exception e) {
                System.out.println("Se ha producido un error inesperado");
                System.out.println(e.toString());
            }
        } else {
            System.out.println("No se ha seleccionado ningun archivo.");
        }
    }


El tema es que no escribe nada, osea lee el archivo bien, lo muestra y cuando llega el momento eliges la opcion del menu que quieres y no crea el archivo traducido.

Esta es mi funcion escribir:
Código (java) [Seleccionar]
public static void escribir(String s, int n) {
        if (n == 1) {
            try {
                FileWriter salida = new FileWriter("C:\\Users\\Tony\\Documents\\NetBeansProjects\\AGonzalezJBalmes\\LeetSpeakResultado1.txt", true);
                for (int i = 0; i < s.length(); i++) {
                    salida.write(s.charAt(i));
                }
                salida.close();
            } catch (IOException ex) {
                Logger.getLogger(Escribir.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else if (n == 2) {
            try {
                FileWriter salida = new FileWriter("C:\\Users\\Tony\\Documents\\NetBeansProjects\\AGonzalezJBalmes\\LeetSpeakResultado2.txt", true);
                for (int i = 0; i < s.length(); i++) {
                    salida.write(s.charAt(i));
                }
                salida.close();
            } catch (IOException ex) {
                Logger.getLogger(Escribir.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

Acabo de empezar hace escasos días con ficheros y no me aclaro muy bien...

Gracias de antemano espero que me podáis ayudar.
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.

Tonyskater

Iba a modificar el post pero pasaban cosas raras con los caracteres prefiero "responderlo"
Este es un ejemplo de Ejecución

No, no crea el archivo, ni salta ningun error, el programa pasa de mi...
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.

Serapis

#2
Normalmente cuando alguien empieza, ni se explica bien, ni pone código (o pone solo 4 líneas), y suele ser un refrito de tripas revueltas. Así que lo primero es felicitarte, porque no caes en ninguna de esas cuestiones.

De entrada, yo te sugeriría que usaras tu alfabeto 1337 tanto en minúsculas como en  mayúsculas. Es decir:
Tal como tienes:
0 1 2 3 4 5 6 7 8 9
o i  z e  a s g t b p

Pero también:
0 1 2 3 4 5 6 7 8 9
O I Z E A S G T B P

de hecho, mucho mejor si todo el texto quedara en mayúsculas, pero bueno... cuando te funcione ya decidirás...

Lo segundo, es señalarte que hacerlo en la forma de 'Replace', en realidad exige recorrer 10 veces el texto, para hacer el cambio. En cada ocasión recorre todo el texto, buscando cada vez una determinada letra que cambiar.
Si el texto es corto (que es lo habitual), no importa, será tan rápido que no se aprecia  ninguna tardanza. Si el texto fuera largo, o lo haces con muchos ficheros podría ser hasta 10 veces más lento de lo que realmente necesita ser.


Para ello, habría que generar un alfabeto, para traducir de uno a otro sistema:

// Esta función podría llamarse al principio, cuando se crea la clase, que alberga el código (se genera una sola vez, se invoca una sola vez).
Funcion CrearTablasDeTraduccion
    //Primero se hace una equivalencia con el ASCII.
    Bucle K desde 0 a 255
       AlfabetoToLeetSpeak(k) = k
       AlfabetoFromLeetSpeak(k)= k
    Fin bucle

    //Luego se hacen los cambios que proceden (manualmente), yo pongo el cambio para 3 caracteres, tu completa el cambio para los 7 restantes...
   AlfabetoToLeetSpeak(111)=48 ' o =0
   AlfabetoToLeetSpeak(79)=48 ' O = 0

   AlfabetoToLeetSpeak(105)=49 ' i =1
   AlfabetoToLeetSpeak(73)=49 ' I = 1

   AlfabetoToLeetSpeak(122)=50 ' z =2
   AlfabetoToLeetSpeak(90)=50 ' Z = 2
  .... resto de letras asignarles desde 3-9

    // Y la traducción de vuelta, es intercambiar los valores previos, elegimos números por mayúsculas, es imposible regresar de números a myúsculas y minúsculas al mismo tiempo, tal como estaban en origen, hay que decantarse y lo hacemos por mayúsculas, porque se parecne más a los números que las minúsculas.
   AlfabetoFromLeetSpeak(48)=79 ' 0 =O

   AlfabetoFromLeetSpeak(49)=73 ' 1 = I

   AlfabetoFromLeetSpeak(50)=90 ' 2 =Z
  .... resto de letras asignarles desde 3-9
Fin funcion

NOTA: que yo solo he puesto la traducción para 3 caracteres, te falta poner las de los otros 7 restantes...


Luego ya se puede usar la tabla (que proceda) en una funcion de traducir.

// Una enumeración para señalar la dirección de traduccion (podría ser remplazado por un valor buleano, eso al gusto, lo dejo así por más claridad).
Enumeracion TipoDeTraduccion
   TraducirALeetSpeak = 0
   TraducirDeLeetSpeak = 1
Fin enumeracion

Funcion Traducir(Texto tipo String, Alfabeto tipo TipoDeTraduccion) Devuelve String // o un array de bytes, según se precise.
    ArrayTexto() tipo Array
    ArrayTexto= Convertir(Texto a bytearray)

    Si Alfabeto = TraducirALeetspeak entonces
        Bucle k desde 0 a ArrayTexto.Longitud
            ArrayTexto(k)= AlfabetoToLeetSpeak(ArrayTexto(k))
        fin bucle
    si no // Tradicr desde LeetSpeak
         Bucle k desde 0 a ArrayTexto.Longitud
            ArrayTexto(k)= AlfabetoFromLeetSpeak(ArrayTexto(k))
        fin bucle
     fin si
     Devolver Convertir(ArrayTexto a String) //no es absolutamente necesario La conversión) si se va a guardar a fichero, al fichero se escriben bytes, poco le importa que tu lo consideres string, char o bytes...
fin funcion


-----------------------

Y ahora mirando tú código... qué falla?.

Bueno falla que tu lees una línea de código, la conviertes y nada más convertirla la escribes a UN NUEVO FICHERO Cada VEZ.
Lo que debes hacer primero es crear el fichero de salida, y luego simplemente es mandar escribir al final del fichero, es decir la acción es APPEND (añadir al final), tu sobrescribes el mismo fichero con cada línea que lees y traduces del origen, y lo cierras con cada vez.
Cuando escribas todas las líneas, (es decir al final del bucle de lectura), es cuando debes cerrar el fichero de escritura.

Por tanto tus pasos (simplificados), serían:
Funcion Traducir(FicheroOrigen, otrosparametros...)
   Si ficheroOrigen no esta vacío ni presenta otros problemas.
       Abrir fichero de escritura: FileWrite
       Abrir fichero de lectura: FileRead
       Por cada Linea en FileRead: LeerLinea
            LineaWrite = Traducir(Linea, DireccionTraduccion)
            FileWrite.Append(LineaWrite)
       fin Cada
       Cerrar FileWrite
   si no
      advertir al usuario: "el fichero introducido, tiene tal o cual problema"
   fin si
fin funcion


Como ves el código es bien sencillo y claro... ahora tu traduce de pseudocódigo...
No olvides controlar las posibles excepciones. que yo no ponga (casi) nada al respecto, obedece a que puedas verlo y entenderlo con claridad....

No he mirado nada más en tu código (solo por encima) y tras ver ese fallo, asumo que no tienes más... en cualquier caso, corrige/modifica y ya veremos si tienes más fallos.

Serapis

Nota que describo dos funciones traducir... hay sobrecarga...

Una traduce un texto, la otra traduce un fichero (y lo guarda en otro).
Pero si te produce confusión, puedes explicitar un nombre diferente para cada una:
TraducirFichero(...)
TraducirTexto(...)

Tonyskater

Cita de: NEBIRE en 22 Mayo 2017, 22:43 PM
Nota que describo dos funciones traducir... hay sobrecarga...

Una traduce un texto, la otra traduce un fichero (y lo guarda en otro).
Pero si te produce confusión, puedes explicitar un nombre diferente para cada una:
TraducirFichero(...)
TraducirTexto(...)


Hola, gracias por responder, lo leí anoche pero no podía contestar.
En principio entiendo lo que me dices y creo que es una buena forma de hacerlo, gracias.
Pero ahora mismo no me preocupa la "fluidez" con que haga la operación ya que es un ejercicio simple de clase y no creo que mi profesor se vaya a poner a traducir libros de texto con mi programa.. O sí, pero no se lo recomiendo... :silbar:

He reducido el problema general a una duda simple, mi cerebro no procesa donde tengo que realizar las operaciones...

Tengo un ejemplo sencillo aislado:

Código (java) [Seleccionar]
public static void main(String[] args) {
        JFileChooser selector = new JFileChooser();
        selector.showOpenDialog(null);
        selector.setFileSelectionMode(JFileChooser.FILES_ONLY);
        if (selector.getSelectedFile() != null) {
            File fichero = selector.getSelectedFile();
            try {
                FileWriter salida = new FileWriter("C:\\Users\\Tony\\Documents\\NetBeansProjects\\AGonzalezJBalmes\\LeetSpeakResultado.txt");
                BufferedWriter bw = new BufferedWriter(salida);
                Scanner entrada = new Scanner(fichero);
                String linea = "";
                //Vamos a leer lo que contiene el fichero que hemos abierto...
                while (entrada.hasNextLine()) {
                    linea = entrada.nextLine();
                    System.out.println(linea);
//                    Mi teoria es que aqui van las operaciones, pero... Con que tengo que operar?
//                    quiero leer el fichero... Lo leo Linea a linea...
//                    y quiero procesar cada linea y escribirla en otro fichero traducida...
//                    hago esto:(Se que esta mal... pero es lo que no entiendo)
                    bw.write(linea.replace('O', '0').replace('I', '1').replace('Z', '2').replace('E', '3').replace('A', '4').replace('S', '5')
                            .replace('G', '6').replace('T', '7').replace('B', '8').replace('P', '9'));
                }
               
                entrada.close();
                salida.close();
            } catch (FileNotFoundException e) {
                System.out.println("Fichero no encontrado");
            } catch (NoSuchElementException e) {
                System.out.println("No es un formato correcto de archivo");
                System.out.println("Es esperaba un fichero de texto.");
            } catch (Exception e) {
                System.out.println("Se ha producido un error inseperado");
                System.out.println(e.toString());
            }
        } else {
            System.out.println("No se ha encontrado ningun archivo");
        }
    }


En los comentarios he situado las dudas...
Gracias de nuevo!
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.

Serapis

#5
No se rompe el ordenador por 'probarlo'...

Si, ese es el sitio exacto donde va.

Yo solo añadiría tras el "write", otro System.out.println(linea); así ves como era la línea a la entrada y tras la conversión... y ahí si observas error, corrige según veas que error arroja... después de todo, siempre cuando se está emepezando es buena práctiva añadir líneas de código extra a modo de debug, para ir probando no solo errores, si no incluso ideas nuevas...

p.d.: de haber sabido antes que era un ejercicio de clase, te lo hubiera dejado para que pensaras un poco más... pero creo sinceramente que lo hubieras hecho, en general la gente es perezosa y no se lo toma demasiado en serio, parece que tú sí...

Tonyskater

Cita de: NEBIRE en 24 Mayo 2017, 03:41 AM
No se rompe el ordenador por 'probarlo'...

Si, ese es el sitio exacto donde va.

Yo solo añadiría tras el "write", otro System.out.println(linea); así ves como era la línea a la entrada y tras la conversión... y ahí si observas error, corrige según veas que error arroja... después de todo, siempre cuando se está emepezando es buena práctiva añadir líneas de código extra a modo de debug, para ir probando no solo errores, si no incluso ideas nuevas...

p.d.: de haber sabido antes que era un ejercicio de clase, te lo hubiera dejado para que pensaras un poco más... pero creo sinceramente que lo hubieras hecho, en general la gente es perezosa y no se lo toma demasiado en serio, parece que tú sí...

Bueno cuando te gusta algo, aunque sea una obligación, no te cuesta nada ponerte, o por lo menos es mi caso...
Aunque lo has dicho bien "parece", creo que solo me tomo enserio las cosas que me interesan, programación es una de ellas, luego hay otras que ni intentándolo... Como puede ser Administración de sistemas, no digo que no lo saque, sino que me da igual que sea un 5 que un 10... No me gusta.

Por otro lado. tengo en clase el código final... a ver si mañana lo cojo y os lo subo para q veáis que tal ha ido. Gracias por la ayuda. ;-) ;-)
Cita de: Manual de mantenimiento de IBM"Todas las piezas deben unirse sin ser forzadas. Debe recordar que los componentes que está reensamblando fueron desmontados por usted, por lo que si no puede unirlos debe existir una razón. Pero sobre todo, no use un martillo"
Mi nombre es Tony y estoy aqui para aprender, pero si hay algo que pueda compartir con vosotros lo haré.