4
\$\begingroup\$

Needing a way to read the number of lines on a web page for the purpose of a progress bar the following method is created:

private static int countPageLines(String url) throws IOException {
        URL page = null;
        BufferedReader in = null;
        int count = 0;

        try {
            page = new URL(url);
            in = new BufferedReader(new InputStreamReader(page.openStream()));

            while ((in.readLine()) != null) {
                count++;
            }
        } catch(IOException ioe) {
            ioe.printStackTrace();
        } finally {
            if (in != null) {
                in.close();
            }
        }

        return count;
    }

Now, of course, it works but is it optimal? Can anything be done to improve the speed? Java 8 is available, if pertinent.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Just curious: how's the number of lines of HTML/JS/CSS pertinent to updating a progress bar? \$\endgroup\$
    – h.j.k.
    Nov 24 '15 at 3:23
  • \$\begingroup\$ One of my friends wanted a way to get the source code on a website, it sounded easy so I made it, for the sake of practice I used a few things for the first time and wanted to also add a progress bar. I could be completely and utterly misguided but I wanted a way to have a sense of how long it would take -- though it's usually fast and feels like doing this, I just make it slower. \$\endgroup\$
    – Legato
    Nov 24 '15 at 15:16
2
\$\begingroup\$

There are a bunch of things which you should consider revising, including the basic concept itself.

Here your concept is to read each line from the URL, count it, and throw it away. Your code does nothing with the data? What's the point?

Regardless, even if the sole purpose of the code is to count a URL's lines, the code should be revised to take advantage of Java Best practices.

First up, it's a cheap shot to treat the new URL(...) constructor the way you do. Yes, it throws a MalformedURLException, and yes, that is a subclass of an IOException, but they really should not be lumped together.

Your method is listed as throwing an IOException anyway, so why handle the exception inside the method and throw nothing? The calling code will need to handle the IOException anyway. Just throw the exception and be done.... but also throw the MalFormedURLException.

Next try-with-resources is your friend. Resources treated that way will not need the finally block at all.

Finally, Java 8 does have some fantastic InputStream-to-Stream methods, use them. Specifically, the BufferedReader.lines() method:

Your code could be something like:

private static int countPageLines(String url) throws IOException {
    URL page = new URL(url);
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(page.openStream()))) {
        long count = reader.lines().count();
        return count > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)count;
    }
}

As a side note, you have tagged your question with . The limiting factor here in terms of performance is your network... I cannot suggest a way to make your code above improve the performance of your network without knowing more about your setup ;-)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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