-1

我目前正在用 Java 编写自己的 Brainfuck 解释器,因为我希望它能够从文件中读取代码,所以我编写了一个BFInputStream过滤掉不必要符号的文件。它看起来像这样:

import java.io.FilterInputStream;
import java.io.InputStream;
import java.io.IOException;

public class BFInputStream extends FilterInputStream {
    public BFInputStream(InputStream in) {
        super(in);
    }
    public int read() throws IOException {
        while(true) {
            int i = super.read();
            // keep LF for line number checking.
            if(i == -1 || i == 10 ||( i >= 43 && i <= 46) || i == 60 || i == 62 || i == 91 || i == 93)
                return i;
        }
    }
    public int read(byte[] b, int off, int len) throws IOException {
        if(off < 0 || len < 0 || len > b.length - off) throw new IndexOutOfBoundsException();
        for(int i=0; i<len; i++) {
            int j = read();
            if(j < 1) return i;
            b[off+i] = (byte)j;
        }
        return len;
    }
}

我的解释器使用LineNumberReader<- InputStreamReader<- BFInputStream<-FileInputStream来读取文件。但每次到达文件末尾时,它都会抛出:

java.io.IOException:基础输入流返回零字节

  at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:268)
  at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
  at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
  at java.io.InputStreamReader.read(InputStreamReader.java:167)
  at java.io.BufferedReader.fill(BufferedReader.java:136)
  at java.io.BufferedReader.read(BufferedReader.java:157)
  at java.io.LineNumberReader.read(LineNumberReader.java:108)
  at Interpreter.run(Interpreter.java:101)
  at Interpreter.main(Interpreter.java:180)

Interpreter.java:101 包含对BFInputStream.read().

我不确定我是否正确理解了异常。我认为流根本没有返回任何字节(因为超时)。我想如果有一大块非 BF 字符,那么这可能是可能的,但在文件末尾?FileInputStream因此FilterInputStream并且BFInputStream应该返回-1。

我的代码有什么问题?

4

2 回答 2

2

if (j < 1)应该是if (j < 0),因为 EOF 由 表示-1。此外,您的方法永远不会在 EOF 处返回 -1。

正确的实现如下所示:

public int read(byte[] b, int off, int len) throws IOException {
    if(off < 0 || len <= 0 || len > b.length - off) throw new IndexOutOfBoundsException();         
    int i = 0;
    while (i < len) {
        int j = read();
        if (j < 0) break; // Stop reading at EOF
        b[off + i] = (byte) j;
        i++;
    }
    if (i == 0) return -1; // If we get EOF with no data, return it to the caller
    else return i;
}
于 2012-06-06T16:18:32.273 回答
1

之前做过同样的事情,但是使用了 File、FileReader/Writer 和 BufferReader/Writer。我给你我用作指导的代码片段.. 试试看

从文件中读取

File f = new File("my.txt");
FileReader fr = new FileReader(f);
BufferedReader br  = new BufferedReader(fr);

String s = null;

while ((br=readLine())!=null) {

// Do whatever u want to do with the content of the file.

}

br.close();

对于写入文件:

Boolean isDone = true;
Scanner scan = new Scanner(System.in);
File f = new File("my.txt");
FileWriter fr = new FileWriter(f);
BufferedWriter br  = new BufferedWriter(fr);

while (b) {

   if (!b) {

 br.write(new Scanner(System.in).nextLine());

 }


}
于 2012-06-06T16:27:33.133 回答