1
$\begingroup$

I'm new at Jlink (and English, so I'm sorry if things aren't clear).

I did a code which tries to scan a file searching for a given word. As a result, I'm supossed to get the line where the given word is found, but I get nothing in the notebook. Here's my code:

Needs["JLink`"]

Scanner[archivo_String, palabra_String] :=
    JavaBlock[
  Module[{entrada, conteolin = 0, conteopal = 0, sc, ruta, leer, lin, 
    st},
   InstallJava[];

   ruta = JavaNew["java.io.File", archivo];
   sc = JavaNew["java.util.Scanner", palabra];

   entrada = JavaNew["java.io.FileReader", ruta];
   leer = JavaNew["java.io.BufferedReader", entrada];

   lin = leer@readLine[];


   While[lin != Null, st = JavaNew["java.util.StringTokenizer", lin];

    conteolin = conteolin + 1;

        While[st@hasMoreTokens[],

      If[st@NextToken[]@equalsIgnoreCase[sc], conteopal++, 

       Print[sc <> "aparece en la linea" <> conteolin]];

      lin = leer@readLine[];
      ]

     If[conteopal > 0, 
      Print["La palabra" <> sc <> "aparece" <> conteopal <> "veces", 
       "no se econtró la palabara"]]
    ];
   ]
  ]

I don´t know if I wrote it wrong, the Jlink docs has info about the Modal and Modeless interaction, do I have to use one of them?

Thank you

$\endgroup$

1 Answer 1

2
$\begingroup$
Needs["JLink`"]

       Scanner[archivo_String, palabra_String] := JavaBlock @ 
         Module[{entrada, conteolin, conteopal, sc, ruta, leer, lin, st},
         conteopal = conteolin = 0; lin = "";
         ReinstallJava[];
         ruta = JavaNew["java.io.File", archivo];
         entrada = JavaNew["java.io.FileReader", ruta];
         leer = JavaNew["java.io.BufferedReader", entrada(*,8*1024*)];
         lin = leer @ readLine[];
         While[ lin =!= Null
            ,
              lin = leer @ readLine[] 
              ; If[! StringQ[lin], Break[]]
              ; conteolin = conteolin + 1
              ; st = JavaNew["java.util.StringTokenizer", lin] 
              ; While[st @ hasMoreTokens[]
                 , proximaToken = st @ nextToken[]
                 ; 
         If[JavaNew["java.lang.String", proximaToken] @ 
           equalsIgnoreCase[palabra]
                      , conteopal++
                      ; 
          Print["La palabra " <> palabra <> " aparece en la linea " <> 
            ToString[conteolin]]
                    ]
                 ] 
          ]
         ; If[conteopal > 0
             , Print @ Row[{"La palabra \"", palabra, "\" aparece ", conteopal
                               , If[conteopal == 1, " vez", " veces"]
                               }
                       ]
             , Print[ "no se encontró la palabara " <> palabra ]
           ]
]

file = FindFile["ExampleData/USConstitution.txt"];
Scanner[file, "Qualification"] // AbsoluteTiming

works, but is really rather slow, somehow, maybe because of the rather slow JLink overhead. So I would either code the logic completely in Java, or, just do something like

AbsoluteTiming[
 lins = Import[file, "Lines"];
 wlins = ImportString[#, "Words"] & /@ lins;
 {Position[wlins, "Qualification"][[All, 1]],
  Count[wlins, "Qualification", -1]}
 ]

which finishes in less than one second, about 20 times faster ...

$\endgroup$
1
  • $\begingroup$ That's right, it's faster. Thank you! $\endgroup$ Commented Jun 16, 2020 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.