如果以“#”开头,​​如何使InputStream跳过一行?

时间:2017-03-07 20:03:54

标签: java multidimensional-array inputstream qr-code

我正在编写一个必须解码QR码的程序。代码在内部表示为2D布尔列表。代码通常被读取为包含1和0的文本文件,其中1表示矩阵中的暗模块(true),0表示光模块(false)。

我必须实现一个方法,它将接受一个I​​nputStream,然后必须返回一个QR码。我必须阅读.txt,其中包含以'#'开头的1s,0和注释行。我需要让方法忽略那些注释行,但我不知道该怎么做。

以下是代码的一些相关部分:

首先是QR代码构造函数(构造函数中使用的所有方法都可以工作并完成它们的工作):

public class QRCode {

private List<List<Boolean>> data; //A 2D Boolean matrix, true means black, false means white.

public QRCode(List<List<Boolean>> data)
{
    if (data == null)
        throw new NullPointerException();
    if (QRCode.isQuadratic(data) == false)
        throw new InvalidQRCodeException("Matrix must be quadratic!");
    if (QRCode.versionCheck(data) < 1 || QRCode.versionCheck(data) > 40)
        throw new InvalidQRCodeException("Invalid Dimensions (Version).");
    if (QRCode.correctlyAlligned(data) != true)
        throw new InvalidQRCodeException("Improper Allignment!");
    if (QRCode.correctTimers(data) != true)
        throw new InvalidQRCodeException("Incorrect Timing Pattern!");
    if (QRCode.correctFormatting(data) != true)
        throw new InvalidQRCodeException("Incorrect Formatting!"); 

    this.data = data; 
}   

}

这是我指的方法。我写的至少是什么。此外,如果.txt文件包含除1s,0和comment之外的任何内容,则应抛出异常。 PS:我之前从未使用过InputStreams,我尝试使用Google搜索,但我找到的所有答案都是针对特定类型的Streams,并且他们使用.readLine()方法,我的IS在这里不允许我使用。

public static QRCode fromFile(InputStream is) throws IOException 
{   
    int i;
    List<List<Boolean>> data = new ArrayList<>(); //a 2D Boolean Matrix
    int y = -1, x = -1;

    if (is == null)
        throw new NullPointerException();
    while((i = is.read())!=-1) //Reading begin
    {
        if (i == (byte) '\n') //If a line in .txt file ends.
        {
            y++; 
            data.add(new ArrayList<Boolean>());
            x = 0;
        }

        if ((char) i == '1') //|| (char) i == '0')
        {
            data.get(y).add(true);
            x++;
        }
        if ((char) i == '0') //||
        {
            data.get(y).add(false);
            x++;
        }
    }


    return new QRCode(data);
}

我要处理的文本文件示例:

# name: small
# type: bool matrix
# rows: 25
# columns: 25
1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 1
1 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 0 0 0 0 1
1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 1 0 0 1 0 1 1 1 0 1
1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 0 0 0 1 0 1 1 1 0 1
1 0 1 1 1 0 1 0 0 0 1 1 1 0 0 0 1 0 1 0 1 1 1 0 1
1 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1
1 1 1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0
1 1 0 1 1 0 1 0 0 1 0 0 1 0 1 1 0 0 1 0 0 0 0 0 1
1 1 1 1 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 1 1 1 0 0 0
1 0 0 1 1 1 1 0 1 1 0 0 1 1 0 1 1 0 1 1 1 0 1 0 1
0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 1 1 1 0
0 1 1 0 0 1 1 1 0 1 1 0 0 0 0 0 1 0 1 1 0 1 0 1 1
1 1 0 0 0 1 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 0
1 1 1 0 0 0 1 1 0 1 0 0 0 1 1 1 1 0 1 0 0 0 0 1 1
1 0 1 1 0 1 0 0 0 0 1 0 1 0 1 0 1 0 0 1 0 1 1 0 1
1 0 1 1 0 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 1 0 1 1 1
0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 1 0 1
1 1 1 1 1 1 1 0 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 1
1 0 0 0 0 0 1 0 0 0 1 1 0 1 1 0 1 0 0 0 1 1 0 0 0
1 0 1 1 1 0 1 0 1 0 0 1 0 1 0 1 1 1 1 1 1 1 0 1 1
1 0 1 1 1 0 1 0 1 0 0 0 1 1 1 0 0 1 1 0 0 0 1 1 1
1 0 1 1 1 0 1 0 0 0 1 1 0 1 0 0 1 1 0 1 1 0 0 1 1
1 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 0 0 1 1 0 1 1 1 1
1 1 1 1 1 1 1 0 1 0 1 1 1 1 0 0 1 0 1 0 0 1 0 0 1

3 个答案:

答案 0 :(得分:1)

首先,我建议您使用Reader来阅读文字。然后,您可以使用BufferedReader及其readLine()方法来处理文本行,而不是字节流。

无论如何,根据您当前的代码:一旦您阅读了\n,请设置一个布尔标志,表示您刚刚看到一个换行符。然后,当您开始阅读下一行时,请打开该标记,如果它是真的,并且您看到#作为下一个字符,则应该阅读,直到看到另一个\n 。如果标志不为真,那么请按原样读取该行的其余部分。

您可能需要在找到#时考虑空格,具体取决于您希望这样做的宽松程度。

答案 1 :(得分:0)

如果您决定使用Reader,那么您可以使用正则表达式来消除包含除“0”和“1”之外的任何字符的行。您可以在链接下找到有关正则表达式用法的详细信息。 How to check if a string contains only digits in Java

您只能修改1和0的正则表达式,如String regex = "[0-1]+";

您可以使用以下示例代码获取每个角色。

String s1="hello";
char[] ch=s1.toCharArray();

答案 2 :(得分:0)

为什么不使用Files.lines代替InputStream

Files.lines(Paths.get("path_to_File.txt")).filter(s -> !s.contains("#"));// let's
//read all lines form the file and skip the lines with `#` symbol

我们可以将每一行转换为Boolean的列表:

s -> Stream.of(s.split(" ")).map("1"::equals).collect(Collectors.toList())// split 
string by ` ` (space) symbol and convert to Boolean "1" - true, "0" - false

现在让我们把所有东西放在一起:

List<List<Boolean>> qr = Files.lines(Paths.get("data/fromFile.txt"))
                .filter(s -> !s.contains("#")).map(
                        s -> Stream.of(s.split(" ")).map("1"::equals)
                            .collect(Collectors.toList())
                ).collect(Collectors.toList());

对于文件:

# name: small
# type: bool matrix
# rows: 1
# columns: 3
1 1 1
1 0 1

输出

[true, true, true]
[true, false, true]