如何用java有选择的输入多行文本

java如何有选择的输入多行文本

今天在作做业的时候碰到了一个问题:要用java作词频统计,可是这就犯难了,java如何有选择性的进行文件输入输出呢?java

查阅文档可知,inputStream类和outputStream类是字节流输入输出,而reader 类和writer 类则是直接Unicode码输入输出,我为了图省事,我最后使用了FileReader类的read方法进行文件读取。FileReader类中的read方法能够逐字符读取,返回类型为int,其实就是0~255的char 类型,只要进行强制类型转换,就能够获得读入的字符,当遇到文件尾的时候,该方法返回-1。由于是char类型,因此若是遇到中文字符,好比句号,就会按照两个char处理。正则表达式

 

接下来解决选择性输入的问题。思路很简单:app

  1.若是如今所读取到的字符不是咱们想要的,那么就一直向下读取,直到读取到咱们想要的函数

  2.若是遇到了返回值为-1的状况,退出,表示文件读取完成(这一步必定要放在中间判断spa

  3.若是如今读取的是咱们想要的,就一直读取,直到出现咱们不须要的,退出,等待下一次读取。code

解释一下第二个为何要在中间判断吧。blog

由于若是放在三个判断的第一个,那么若是文件以无用的字符结尾,则最后一个单词输出后还会多余输出一个换行,由于return了一个空的StringBuffer,而输出语句用的是println。文档

若是放在三个判断中的最后,那么若是文件以有用单词结尾,则最后一个单词没法输出,由于扫描到单词后紧接着就是read返回-1,此时就直接返回“字符串完成”,因此少最后一个单词字符串

 

第一次解决的时候,由于判断1的位置和判断3混在了一块儿,因此出现了最后一个单词不能输出的状况。input

  错误写法我也写下来吧,以避免之后再错:

错误1——放在最前面:

private String read() throws IOException{
        StringBuffer strBuf = new StringBuffer();
        int t=fileReader.read();
        if(t==-1) return "\\$";

错误2——放在最后:

1 while(t!=-1&&isAlph((char)t)){
2             strBuf.append((char) t);
3             t=fileReader.read();
4         }     
5     if(t==-1) return "\\$";
6     return strBuf.toString();
7 }

正确作法:(彻底代码,而且简化了不须要的流程)

 1 private String read() throws IOException{
 2         StringBuffer strBuf = new StringBuffer();
 3         int t=fileReader.read();
 4         if(t==-1) return "\\$";
 5         while(t!=-1&&isAlph((char)t)){
 6             strBuf.append((char) t);
 7             t=fileReader.read();
 8         }
 9         return strBuf.toString();
10     }

 

所以,能够看到代码的细节也是不容忽视的,同一句话,不一样位置,致使结果截然不同。

 

======================================我是小清新的分割线=========================================

2016.5.8更新

嗯,好吧,我又来啦,此次的java之旅差很少就已经完成啦,如今让咱们梳理一下此次学到的输入流的组合方式:

除了上文中逐个字符进行输入的方法以外,对于有些问题,正则表达式可能更加好用。

好比咱们想逐行读取文本怎么办呢,咱们会发现FileReader类中是没有这种方法的,所以咱们须要把File类和其余输入流组合起来,自力更生。好比咱们把File和Scanner类结合起来,熟悉控制台的小伙伴们必定很清楚,Scanner经常使用来进行控制台输入,而且Scanner能够一次读取一行,所以,咱们就选它啦。

所以我么能够愉快地一次一行进行操做啦

定义以下:(in 和 out 分别是输入流和输出流)

public Tree_T_Display(File fin,File fout) throws IOException {
        in = new Scanner(new FileInputStream(fin));
        out = new FileWriter(fout);
}

这样read()函数就能够这样定义啦:

public String read()throws IOException{
        if(in.hasNext()){
            String s = in.nextLine();
            s=s.replaceAll(" ", "");//去掉空格
            return s;
        }
        return null;
    }

这样一来,配合正则表达式,咱们的代码量能够减小,而且在过滤数据方面也能够交给正则表达式去作。

另外,正则表达式也提一下吧,在java的正则表达式我本身用过的有两种调用方法,一种是String类中的split,matches方法,注意split方法中匹配上的字符不会出如今新的字符串中,而matches方法中的正则必须和字符串彻底匹配,不然就返回false。

另外,正则中,+表示1~n个(n)不限制,*表示0~n个,和{1,}  {0,}分别等价。

^表示行开头,$表示行结尾,^在[]中表示“非”,取补集

举例以下

目标:匹配“单词”开头+“(”结尾的字符串:

1 s.matches("^[a-zA-Z]+[^\\(]$")

匹配可能有特殊字符的单词,缩写等:

1 s.matches("^[^ ]+$")

这里就用到了^在[]中的状况,一个[]是一个可匹配的类,上面第二行做用是匹配一个“以非空格开头而且以之为结尾的字符串”

pte String read() throws IOException{
StringBuffer strBuf = new StringBuffer();
int t=fileReader.read();
if(t==-1) return "\\$";
while(t!=-1&&isAlph((char)t)){
strBuf.append((char) t);
t=fileReader.read();
}
//保留最大单词长度,为格式化输出作准备
maxLen = maxLen < strBuf.length() ? strBuf.length() : maxLen;
return strBuf.toString();}
相关文章
相关标签/搜索