0

我在这里有一堂课,在那里我阅读网页的来源并搜索特定的值。这通常需要 1 秒才能完成,但我希望它更短。我的第一个猜测是,这个值通常在页面的一半,所以我可能只读到一半。

public class ReadData {
     public static void main(String[] args) throws IOException {
             StringBuilder line = new StringBuilder(1000000);

         URL url = new URL(url);
         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
         BufferedReader rd = new BufferedReader(new InputStreamReader(conn
                 .getInputStream()));
         while (rd.readLine() != null) {
             line.append(rd.readLine());
             }

         long start = line.indexOf(startReading);
         long finish = line.indexOf(finishReading);
         String value= line.substring((int)start + 1, (int)finish);
         System.out.println("VALUE: " + value);

        }
}

所以现在我阅读了整个文本,然后找到startReadingandfinishReading字符串,我得到了它们之间的值。finishReading在找到字符串之前,我如何才能阅读源代码?或者有什么方法可以加快阅读速度?

提前致谢!

4

3 回答 3

2

您当前的版本将整个文档读入内存,然后通过搜索内存中的副本来查找您感兴趣的位。

更好的方法是一次读取文档一行,查找包含开始和结束字符串的行。只有在获得“开始”线时才开始保存,并在获得停止线时完全停止。

这是否会显着加快您的应用程序取决于当前花费的时间。如果大部分(挂钟)时间都在启动 JVM,发送请求并等待文档开始到达,这将无济于事。同样,如果“开始”和“结束”之间的文本是文档的大部分内容,也无济于事。


其他几点注意事项:

  1. 您编写的程序将丢弃输入中的换行符。如果是文本,则可能导致连续的单词跨行边界连接。
  2. 你最后没有关闭阅读器,你会导致资源(文件描述符)泄漏。
  3. 预先分配一个巨大的 StringBuilder 可能是个坏主意……除非您对它需要多大有一个很好的估计。
于 2013-04-14T12:22:04.977 回答
0
while (rd.readLine() != null) {
    String temp=rd.readLine() ;
    line.append(temp);
    if(temp.contains(finishReading))
        break;
}
于 2013-04-14T12:11:58.133 回答
0

要实现更短的时间,您可以在文件读取期间检查/搜索文本。老实说,这取决于原始文本是否根本没有新行(如果是这种情况,性能将相同)。

但在解决这个问题之前,我相信您从 URL 中读取的方式是错误的!您在第二次调用期间添加字符串时调用了readLine ()方法两次!所以你在每次迭代中都跳过了一行!

它认为应该这样做:

public class ReadData {

    public static void main ( String [] args ) throws IOException {

        StringBuilder text = new StringBuilder ();

        URL url = new URL ( url );
        HttpURLConnection conn = (HttpURLConnection) url.openConnection ();
        BufferedReader rd = new BufferedReader ( new InputStreamReader ( conn.getInputStream () ) );

        String line = null;
        while ( ( line = rd.readLine () ) != null ) {
            text.append ( line );
            text.append ( "\n" );
        }

        rd.close ();

    }
}

现在要搜索您需要的介于startReadingendReading之间的文本值,您可以这样做:

public static void main ( String [] args ) throws IOException {

    // Calendar object used to know when the iteration started
    Calendar start = Calendar.getInstance ();
    SimpleDateFormat displayDate = new SimpleDateFormat ( "HH:mm:ss SSS" );
    System.out.println( "Iteration started at : " + displayDate.format ( start.getTime () ) );

    String line = null;
    boolean startReadingFound = false;
    boolean endReadingFound = false;
    while ( ( line = rd.readLine () ) != null ) {
        text.append ( line );
        text.append ( "\n" );

        // Check if 'startReading' is previously found
        if ( startReadingFound == false ) {
            // Search for the 'startReading' string
            int startIndex = line.indexOf ( startReading );
            if ( startIndex != -1 ) {
                // 'startReading' found
                startReadingFound = true;
                // Search for the 'endReading' string, it may be on the same line
                int endIndex = line.indexOf ( endReading );
                if ( endIndex == -1 ) {
                    // 'endReading' not found
                    value.append ( line.substring ( startIndex + startReading.length () ) );
                    value.append ( "\n" );
                }
                else {
                    // 'endReading' found
                    endReadingFound = true;
                    value.append ( line.substring ( startIndex + startReading.length () , endIndex ) );
                    value.append ( "\n" );
                }
            }
        }
        // Check if 'endReading' is previously found
        else if ( endReadingFound == false ) {
            // Search for the 'endReading' string
            int endIndex = line.indexOf ( endReading );
            if ( endIndex == -1 ) {
                // 'endReading' not found
                value.append ( line );
                value.append ( "\n" );
            }
            else {
                // 'endReading' found
                endReadingFound = true;
                value.append ( line.substring ( 0 , endIndex ) );
                value.append ( "\n" );
            }
        }
    }

    rd.close ();

    // Calendar object used to know when the iteration ended
    Calendar end = Calendar.getInstance ();
    System.out.println( "Iteration ended at : " + displayDate.format ( end.getTime () ) );
    System.out.println( "Iteration duration : " + ( end.getTimeInMillis () - start.getTimeInMillis () ) + " milliseconds." );

}

如您所见,首先您可以开始在每一行中查找startReading字符串。如果找到它,则开始添加(在开始阅读字符串之后)行,直到找到endReading字符串。

为了知道在 while 循环中花费的确切时间,我添加了我正在显示的日历对象,因此您可以知道确切的持续时间(以毫秒为单位)。

试试看,如果它解决了你的问题,请告诉我。

于 2013-04-15T08:24:20.447 回答