ZetCode

Java StringReader 类

最后修改时间:2025 年 4 月 16 日

java.io.StringReader 类是一个字符流,它从字符串中读取字符。 它实现了 ReadableCloseable 接口。 当您需要将字符串视为字符输入流时,此类非常有用。

StringReader 提供了所有标准的 reader 方法,但其数据来源于内存中的字符串。 该类维护一个内部位置指针来跟踪读取进度。 它不是线程安全的,不能用于并发访问。

StringReader 类概述

StringReader 扩展了 Reader,并为字符串提供字符流功能。 主要方法包括读取操作、标记/重置功能和流跳过。 该类高效地处理字符串数据,而无需 I/O 开销。

public class StringReader extends Reader {
    public StringReader(String s);
    public int read();
    public int read(char[] cbuf, int off, int len);
    public long skip(long ns);
    public boolean ready();
    public boolean markSupported();
    public void mark(int readAheadLimit);
    public void reset();
    public void close();
}

上面的代码显示了 StringReader 提供的关键方法。 这些方法允许使用流语义从字符串中读取字符。 该类完全支持字符串数据的标记和重置操作。

创建 StringReader

StringReader 通过将字符串传递给其构造函数来创建。 该字符串成为所有读取操作的字符源。 reader 维护自己的位置,独立于原始字符串。

Main.java
import java.io.StringReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String data = "Hello, StringReader!";
        
        try (StringReader reader = new StringReader(data)) {
            System.out.println("StringReader created successfully");
            
            // Read first character
            int firstChar = reader.read();
            System.out.println("First character: " + (char) firstChar);
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了如何创建基本的 StringReader。 try-with-resources 语句确保正确关闭流。 read 方法在流结束时返回 -1。 每个字符都从源字符串中按顺序读取。

从 StringReader 读取字符

StringReader 提供了多种读取字符的方法。 最简单的方法是读取单个字符。 更有效的方法是将多个字符读取到数组中。 所有读取操作都会前进内部位置指针。

Main.java
import java.io.StringReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String text = "The quick brown fox jumps over the lazy dog";
        
        try (StringReader reader = new StringReader(text)) {
            int charValue;
            System.out.println("Reading characters one by one:");
            
            while ((charValue = reader.read()) != -1) {
                System.out.print((char) charValue);
            }
            
            System.out.println("\n\nReading complete");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例显示了如何从 StringReader 中按顺序读取所有字符。 while 循环持续进行,直到 read 返回 -1(流结束)。 每个字符在读取时都会被打印出来。 该流在 try 块结束时自动关闭。

将字符读取到数组中

为了获得更好的性能,请一次性将多个字符读取到 char 数组中。 这减少了方法调用的开销。 read 方法返回实际读取的字符数,该字符数可能小于请求的字符数。

Main.java
import java.io.StringReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String data = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
        
        try (StringReader reader = new StringReader(data)) {
            char[] buffer = new char[10];
            int charsRead;
            
            while ((charsRead = reader.read(buffer)) != -1) {
                System.out.println("Read " + charsRead + " chars: " + 
                    new String(buffer, 0, charsRead));
            }
            
            System.out.println("All characters read");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了批量读取到字符数组中。 缓冲区大小 (10) 决定了一次读取多少个字符。 charsRead 值表示实际读取的字符数。 String 构造函数将缓冲区的相关部分转换为字符串。

Mark 和 Reset 功能

StringReader 支持标记和重置操作以重新读取数据。 mark 方法标记当前位置,reset 返回到该位置。 readAheadLimit 参数指定标记失效前的最大前瞻。

Main.java
import java.io.StringReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        
        try (StringReader reader = new StringReader(text)) {
            // Read first 5 characters
            char[] part1 = new char[5];
            reader.read(part1);
            System.out.println("First part: " + new String(part1));
            
            // Mark current position
            reader.mark(10);
            
            // Read next 5 characters
            char[] part2 = new char[5];
            reader.read(part2);
            System.out.println("Second part: " + new String(part2));
            
            // Reset back to mark
            reader.reset();
            
            // Read again from marked position
            reader.read(part2);
            System.out.println("Second part after reset: " + new String(part2));
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了标记和重置功能。 标记在读取前 5 个字符后设置。 在读取接下来的 5 个字符后,reset 返回到标记的位置。 readAheadLimit 为 10 意味着在标记后读取超过 10 个字符将使标记失效。

跳过流中的字符

skip 方法允许跳过流中指定数量的字符。 这比读取和丢弃数据更有效。 如果到达结尾,则实际跳过的字符数可能小于请求的字符数。

Main.java
import java.io.StringReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String data = "1234567890ABCDEFGHIJ";
        
        try (StringReader reader = new StringReader(data)) {
            System.out.println("Initial content: " + data);
            
            // Skip first 10 characters
            long skipped = reader.skip(10);
            System.out.println("Skipped " + skipped + " characters");
            
            // Read next character
            int nextChar = reader.read();
            System.out.println("Next character: " + (char) nextChar);
            
            // Try to skip beyond end
            skipped = reader.skip(20);
            System.out.println("Skipped " + skipped + " characters (end approached)");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例显示了如何在 StringReader 中跳过字符。 第一个 skip 移动到数字字符之后。 第二个 skip 尝试跳过 20 个字符,但只跳过剩余的字母字符。 skip 方法返回实际跳过的字符数。

使用 ready() 检查就绪状态

ready 方法检查 reader 是否已准备好被读取。 对于 StringReader,除非流已关闭,否则此方法始终返回 true。 它对于与其他 Reader 实现保持一致性很有用。

Main.java
import java.io.StringReader;
import java.io.IOException;

public class Main {

    public static void main(String[] args) {
        String text = "Test string for ready() method";
        
        try (StringReader reader = new StringReader(text)) {
            System.out.println("Reader ready? " + reader.ready());
            
            // Read first character
            System.out.println("First char: " + (char) reader.read());
            
            System.out.println("Still ready? " + reader.ready());
            
            // Close and check
            reader.close();
            System.out.println("Ready after close? " + reader.ready());
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

此示例演示了 ready 方法的行为。 StringReader 始终处于就绪状态,直到关闭。 关闭后,ready 返回 false。 此方法主要用于与其他可能在读取时阻塞的 Reader 类型兼容。

来源

Java StringReader 类文档

在本文中,我们介绍了 Java StringReader 类的基本方法和功能。 理解这些概念对于在 Java 应用程序中使用基于字符串的字符流至关重要。

作者

我叫 Jan Bodnar,是一名经验丰富的敬业程序员。 我于 2007 年开始撰写编程文章,至今已撰写超过 1,400 篇文章和 8 本电子书。 凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程