Java 如何读取字符串直到找到一个“quot;”;“文本”;在它里面(或者以某种方式使阅读速度更快)?

Java 如何读取字符串直到找到一个“quot;”;“文本”;在它里面(或者以某种方式使阅读速度更快)?,java,android,string,Java,Android,String,我在这里有一个类,在那里我阅读一个网页的来源并搜索一个特定的值。这通常需要1秒才能完成,但我希望它更短。我的第一个猜测是,这个值通常位于页面的一半,因此我可能只读取它的一半 public class ReadData { public static void main(String[] args) throws IOException { StringBuilder line = new StringBuilder(1000000); UR

我在这里有一个类,在那里我阅读一个网页的来源并搜索一个特定的值。这通常需要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);

        }
}
现在我阅读全文,然后找到
startReading
finishReading
字符串,然后得到它们之间的值。在找到
finishReading
字符串之前,如何仅读取源代码?或者有没有办法让阅读速度更快


提前谢谢

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

while (rd.readLine() != null) {
    String temp=rd.readLine() ;
    line.append(temp);
    if(temp.contains(finishReading))
        break;
}
更好的方法是一次读取一行文档,查找包含起始字符串和结束字符串的行。只有当你得到“开始”行时才开始保存,当你得到停止行时就完全停止

这是否会大大加快应用程序的速度取决于当前所花的时间。如果(挂钟)的大部分时间都在启动JVM,那么发送请求并等待文档开始到达,这不会有多大帮助。类似地,如果“开始”和“结束”之间的文本是文档的大部分内容,这也没有帮助


还有几点需要注意:

  • 您编写的程序将丢弃输入中的换行符。如果是文本,则可能会导致跨行边界连接连续单词
  • 最后没有关闭读卡器,导致资源(文件描述符)泄漏
  • 预先分配一个巨大的StringBuilder可能是个坏主意。。。除非你有一个很好的估计,它需要有多大

  • 为了缩短时间,您可以在文件读取期间检查/搜索文本。这完全取决于原始文本是否没有新行(如果是这种情况,性能将是相同的)

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

    它认为应该这样做:

    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." );
    
    }
    
    公共类ReadData{
    公共静态void main(字符串[]args)引发IOException{
    StringBuilder text=新的StringBuilder();
    URL=新URL(URL);
    HttpURLConnection conn=(HttpURLConnection)url.openConnection();
    BufferedReader rd=新的BufferedReader(新的InputStreamReader(conn.getInputStream());
    字符串行=null;
    而((line=rd.readLine())!=null){
    text.append(行);
    text.append(“\n”);
    }
    rd.close();
    }
    }
    
    现在,要搜索所需的文本值(介于开始阅读结束阅读之间),可以通过以下方式进行搜索:

    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." );
    
    }
    
    如您所见,首先您可以开始在每行中查找startreding字符串。如果找到它,则开始添加(在开始读取字符串之后)行,直到找到结束读取字符串

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


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

    为什么要添加Android标签?我猜大部分时间可能都花在了连接该URL上。您浪费了一半的线路。只需使用一个rd.readLine();非常感谢您的代码,我将尽快试用。但是如果我真的错过了每一行,我会感到惊讶。是的,在每次迭代中,您都会检索两行:第一行跳过,第二行存储。每次调用rd.readLine(),您都会检索到一行新行。非常感谢您的注释,我在某个地方读到,预分配StringBuilder会加快读取速度,但不会对其产生影响,因此我将删除它。@JaniBela-如果您对缓冲区需要多大有一个良好的估计,预分配是一个好主意。但是预先分配一个随机的大缓冲区是个坏主意。您要做的是分配一个大的
    char[]
    ,该数组中的元素都需要设置为默认值。在你的情况下,有一百万个!谢谢,我已经试过了,但是用这个并没有加快速度。