简体   繁体   中英

Why is this loop becoming infinite when using String.valueOf or Float.toString?

I am reading in bytes from a file using a FileInputStream . The code (in its correct form) is as follows:

String s = "";
try {
        File file = new File(...);
        FileInputStream file_input = new FileInputStream(file);
        DataInputStream data_in = new DataInputStream(file_input );

        while (true) {
            try {
                for (int index = 0; index < 4; index++) {
                    byteArray[index] = data_in.readByte();
                }         
            } catch (EOFException eof) {
                break;
            }

            float f = readFloatLittleEndian(byteArray); // transforms 4 bytes into a float
            //s += Float.toString(f); <- here's the problem 
        }
        data_in.close();
    } catch (IOException e) {
        System.err.println(e.toString());
    }
}
System.out.print(s);

If I run this code as is, then the loop finishes when reading all of the file and transforming each set of 4 bytes into a float .

However, if I uncomment that line, the file never finishes, and seems to loop through the file over and over. Also, printing f (without using Float.toString or String.valueOf ) will not turn this into an infinite loop.

The loop does not become infinite - just grossly inefficient. The problem with the += on java.lang.String is that it produces a new immutable object, discarding the one that it held before. Each time it makes a copy, making the process an O(n 2 ) in terms of the number of entries in your file.

The fix is straightforward - replace String s with StringBuilder s , and use append in place of += .

StringBuilder s = new StringBuilder();
try {
    File file = new File(...);
    FileInputStream file_input = new FileInputStream(file);
    DataInputStream data_in = new DataInputStream(file_input );
    while (true) {
        try {
            for (int index = 0; index < 4; index++) {
                byteArray[index] = data_in.readByte();
            }         
        } catch (EOFException eof) {
            break;
        }
        float f = readFloatLittleEndian(byteArray); // transforms 4 bytes into a float
        s.append(f); 
    }
    data_in.close();
} catch (IOException e) {
    System.err.println(e.toString());
}
System.out.print(s);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM