我习惯于使用c风格的getchar()
, 但在Java中好像没有类似的函数。我正在构建一个词法分析器,需要逐个字符地读取输入。
我知道可以使用扫描器(Scanner)扫描标记或行并通过标记逐个字符解析,但对于跨越多行的字符串来说似乎有些麻烦。在Java中是否有一种方法只获取输入缓冲区中的下一个字符呢,还是我需要继续使用Scanner类?
输入是一个文件,不是键盘。
我习惯于使用c风格的getchar()
, 但在Java中好像没有类似的函数。我正在构建一个词法分析器,需要逐个字符地读取输入。
我知道可以使用扫描器(Scanner)扫描标记或行并通过标记逐个字符解析,但对于跨越多行的字符串来说似乎有些麻烦。在Java中是否有一种方法只获取输入缓冲区中的下一个字符呢,还是我需要继续使用Scanner类?
输入是一个文件,不是键盘。
public class CharacterHandler {
//Java 7 source level
public static void main(String[] args) throws IOException {
// replace this with a known encoding if possible
Charset encoding = Charset.defaultCharset();
for (String filename : args) {
File file = new File(filename);
handleFile(file, encoding);
}
}
private static void handleFile(File file, Charset encoding)
throws IOException {
try (InputStream in = new FileInputStream(file);
Reader reader = new InputStreamReader(in, encoding);
// buffer for efficiency
Reader buffer = new BufferedReader(reader)) {
handleCharacters(buffer);
}
}
private static void handleCharacters(Reader reader)
throws IOException {
int r;
while ((r = reader.read()) != -1) {
char ch = (char) r;
System.out.println("Do something with " + ch);
}
}
}
上述代码的问题在于它使用了系统默认的字符集。在可能的情况下,应优先选择已知编码(最好是Unicode编码)。有关更多信息,请参见Charset类。(如果您感到痛苦,可以阅读此字符编码指南)。
(您可能需要注意的一件事是补充的Unicode字符 - 需要两个字符值来存储的字符。请参见Character类以获取更多细节;这是一个边缘案例,可能不适用于作业。)
read()
的调用来自 RAM 而不是操作系统/磁盘。代码可以在没有缓冲区的情况下工作,或者您可以使用 BufferedInputStream 或通过调用 read(char[])
使用自己的缓冲区。 - McDowell参考其他人的建议,结合字符编码和缓冲输入的要求,以下是我认为比较完整的答案。
假设您有一个代表要读取的文件的File
对象:
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(file),
Charset.forName("UTF-8")));
int c;
while((c = reader.read()) != -1) {
char character = (char) c;
// Do something with your character
}
另一种选择是不逐个字符地读取内容,而是将整个文件读入内存。如果您需要多次查看字符,则这很有用。一种简单的方法是:
/** Read the contents of a file into a string buffer */
public static void readFile(File file, StringBuffer buf)
throws IOException
{
FileReader fr = null;
try {
fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
char[] cbuf = new char[(int) file.length()];
br.read(cbuf);
buf.append(cbuf);
br.close();
}
finally {
if (fr != null) {
fr.close();
}
}
}
将您的输入流包装在缓冲读取器中,然后使用read方法逐个字节读取,直到流的末尾。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Reader {
public static void main(String[] args) throws IOException {
BufferedReader buffer = new BufferedReader(
new InputStreamReader(System.in));
int c = 0;
while((c = buffer.read()) != -1) {
char character = (char) c;
System.out.println(character);
}
}
}
如果我是你,我会使用扫描仪并使用“.nextByte()”方法。你可以将其转换为字符类型,就可以了。
BufferedReader
,则有几个选项可供选择。这个缓冲读取器比Reader更快,因此您可以将其包装起来。BufferedReader reader = new BufferedReader(new FileReader(path));
reader.read(char[] buffer);
这个函数将一行读入到字符数组中。你有类似的选项。请查看文档。
使用BufferedReader将读者包裹起来,它维护一个缓冲区,从而实现更快的整体读取。然后可以使用read()方法读取单个字符(需要进行类型转换)。还可以使用readLine()方法获取整行文本,然后将其拆分为单个字符。如果需要,BufferedReader还支持标记和返回,因此可以多次读取一行。
一般来说,您应该在实际使用的任何流之上使用BufferedReader或BufferedInputStream,因为它们维护的缓冲区将使多次读取变得更快。
在Java 5中添加了新功能,即Scanner方法,它提供了在Java中逐个字符读取输入的机会。
例如; 要使用Scanner方法,请导入java.util.Scanner; 然后在主方法中:定义
Scanner myScanner = new Scanner(System.in); //用于读取字符
char anything=myScanner.findInLine(".").charAt(0);
您可以存储任何单个字符,如果要读取更多字符,请声明更多对象,如anything1、anything2... 有关您的答案的更多示例,请在手头查看(复制/粘贴)
import java.util.Scanner;
class ReverseWord {
public static void main(String args[]){
Scanner myScanner=new Scanner(System.in);
char c1,c2,c3,c4;
c1 = myScanner.findInLine(".").charAt(0);
c2 = myScanner.findInLine(".").charAt(0);
c3 = myScanner.findInLine(".").charAt(0);
c4 = myScanner.findInLine(".").charAt(0);
System.out.print(c4);
System.out.print(c3);
System.out.print(c2);
System.out.print(c1);
System.out.println();
}
}
这将从文件中每行打印1个字符。
try {
FileInputStream inputStream = new FileInputStream(theFile);
while (inputStream.available() > 0) {
inputData = inputStream.read();
System.out.println((char) inputData);
}
inputStream.close();
} catch (IOException ioe) {
System.out.println("Trouble reading from the file: " + ioe.getMessage());
}