前面我们介绍了字节流,但是字节流有一个问题,如果需要打印或者在控制台显示文件中的内容,如果文件中还有中文,不同编码一个中文字符占用的字节数是不固定的,这就会造成输出乱码的情况,那么如何避免这种情况?这里就引入了字符流
为什么要使用字符流?
因为使用字节流操作汉字或特殊符号语言的时候容易乱码,因为汉字不止一个字节,为了解决这个问题,建议使用字符流。
什么情况下使用字符流?
一般可以用记事本打开的文件,我们可以看到内容不乱码的。就是文本文件,可以使用字符流。而操作二进制文件(比如图片、音频、视频)必须使用字节流。
字符输入流:Reader
public String ReadFile(String filepath) throws IOException{
File srcFile = new File(filepath);
Reader in = new FileReader(srcFile);
int length = 0;
//每次读取一个字符,读完位置,读完字符流in也消费完毕。
while ((length = in.read()) != -1) {
System.out.print((char)length);
}
//输出字符串
Reader inS = new FileReader(srcFile);
char[] buffer = new char[10];
StringBuffer sBuffer = new StringBuffer();
while ((length = inS.read(buffer)) != -1) {
sBuffer.append(new String(buffer,0,length));
}
in.close();
System.out.println("---------");
return new String(sBuffer);
}
public static void main(String[] args) throws IOException {
String filepath = "D:" + File.separator
+ "inputstream" + File.separator + "filereader.txt";
FileReaderAndWriter fileReaderAndWriter = new FileReaderAndWriter();
String a = fileReaderAndWriter.ReadFile(filepath);
System.out.println(a);
}
使用字符流完成文件的复制
public void DoFileCopy(String srcfilepath, String descfilepath) throws IOException{
File srcFile = new File(srcfilepath);
File descFile = new File(descfilepath);
Reader in = new FileReader(srcFile);
//重复写入后面加true
Writer out = new FileWriter(descFile,true);
char[] buffer = new char[10];
int length = 0;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
//.trim()可以去掉空格
//写入之后换行\r\n 一般一起用,用来表示键盘上的回车键,也可只用 \n。
//可以用out.write(System.getProperty("line.separator"));
out.write("\n");
out.close();
in.close();
}
public static void main(String[] args) throws IOException {
String srcfilepath = "D:" + File.separator
+ "inputstream" + File.separator + "filereader.txt";
String descfilepath = "D:" + File.separator
+ "inputstream" + File.separator + "filereadercopy.txt";
FileCopy fileCopy = new FileCopy();
fileCopy.DoFileCopy(srcfilepath, descfilepath);
}
cookies
通过包装流统计文件中指定字符串出现的个数
public void FindStringCount(String filepath, String targetstring) throws IOException{
File file = new File(filepath);
FileReader fr = new FileReader(file);
BufferedReader bf = new BufferedReader(fr);
String line = null;
int count = 0;
while ((line = bf.readLine()) != null) {
int index = 0;
//这里是while
while (line.contains(targetstring)) {
index = line.indexOf(targetstring);
//substring方法包含前不包含后
line = line.substring(index+targetstring.length());
count++;
}
}
System.out.println("一共有" + count + "个指定字符串");
}
上面是查询文件中还有多少个指定的字符,需要注意的重点是统计字符串的时候是否包含重复项
line = line.substring(index+targetstring.length());
这里到底是等于index+1还是index+targetstring.length()
简单拓展一下,查询一个字符串中的指定字符串的个数
String b = "ababababababa";
String c = "aba";
int count = 0;
int index = 0;
while (b.contains(c)) {
index = b.indexOf(c);
//不包含重复项
b = b.substring(index + c.length());
//包含重复项
b = b.substring(index + 1);
System.out.println(b);
count++;
}
System.out.println(count);
读取指定文件中的数据,要求:一个一个跳着读,如文件内容:ABCDEF,读取结果为ACE
public String ReadFileJump(String filepath) throws IOException {
Reader in = new FileReader(new File(filepath));
int length = 0;
int i = 0;
StringBuffer sBuffer = new StringBuffer();
// 一个字符一个字符读取
while ((length = in.read()) != -1) {
// 隔一个字符一读取
if (i % 2 == 0) {
System.out.print((char) length);
sBuffer.append((char) length);
}
i++;
}
return new String(sBuffer);
}
读取指定文件夹下包含特定字符的文件
public class FileAndDictionary {
public static void getFile(File file){
//第一级子目录
//定义一个链表保存符合要求的文件
List<File> fileList = new ArrayList<File>();
File[] files = file.listFiles();
for (File f : files) {
System.out.println(f);
//contains是是否包含该字段,包括后缀,算全匹配;startWith和endWith只能总最前面或这最后面匹配
if (f.getName().toLowerCase().contains("file")) {
fileList.add(f);
}
if (f.isDirectory()) {
//递归
getFile(f);
}
}
System.out.println("------");
for (File file2 : fileList) {
System.out.println(file2);
}
//System.out.println(fileList);
}