目录
字符流
字符流出现的原因:由于字节流操作中文不是特别方便,常常需要根据编码方式选择每次读取的字节数,所以,java就提供了字符流。
字符流:字节流 + 编码方式。
字符流只能操作文本文件。
String的编解码
方法名 | 描述 |
---|---|
public byte[] getBytes() | 使用平台的默认字符集将此 String编码为 byte 序列,并将结果存储到一个新的 byte 数组中 |
public byte[] getBytes(String charsetName) | 使用指定名称的字符集将此String编码为byte序列,并将结果存储到一个新的byte数组中 |
public String(byte[] bytes) | 通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String |
public String(byte[] bytes, String charsetName) | 通过使用指定的字符集解码指定的byte数组,构造一个新的String |
使用平台默认的字符集编解码
package org.westos.demo;
import java.util.Arrays;
/**
* @author lwj
* @date 2020/5/25 18:47
*/
public class MyTest {
public static void main(String[] args) {
/*
编码:把字符串按照编码方式转换为字节数组,把看得懂的变为看不懂的
解码:把字节数组按照编码方式转换为字符串,把看不懂的变为看的懂的
*/
String s = new String("黑龙江");
byte[] bytes = s.getBytes();
//使用默认编码方式编码
System.out.println(Arrays.toString(bytes));
//[-23, -69, -111, -23, -66, -103, -26, -79, -97]
String s1 = new String(bytes);
//使用默认编码方式解码
System.out.println(s1);
//黑龙江
}
}
使用GBK编码字符串,再使用"UTF-8"解码
package org.westos.demo;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* @author lwj
* @date 2020/5/25 18:51
*/
public class MyTest2 {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = new String("中文乱码问题");
byte[] bytes = s.getBytes("GBK");
//使用GBK编码方式编码
System.out.println(Arrays.toString(bytes));
//[-42, -48, -50, -60, -62, -46, -62, -21, -50, -54, -52, -30]
String s1 = new String(bytes, StandardCharsets.UTF_8);
//使用UFT-8编码方式解码
//public String(byte[] bytes, Charset charset)
System.out.println(s1);
//������������
//编码解码方式不同,产生中文乱码问题
}
}
使用GBK编解码
package org.westos.demo;
import java.io.UnsupportedEncodingException;
/**
* @author lwj
* @date 2020/5/26 8:50
*/
public class MyTest3 {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = new String("GBK编码的字符串");
byte[] bytes = s.getBytes("GBK");
//使用GBK编码字符串
String s1 = new String(bytes, "GBK");
//使用GBK进行解码字符串
System.out.println(s1);
//GBK编码的字符串
}
}
用什么编码,就用什么解码。
OutputStreamWriter
public class OutputStreamWriter extends Writer { }
构造方法
OutputStreamWriter(OutputStream out)
//使用默认编码输出数据
OutputStreamWriter(OutputStream out, String charsetName)
OutputStreamWriter(OutputStream out, Charset cs)
//使用指定编码输出数据
字符流,就是在字节流的基础上,设置字符集参数。
参数是OutputStream字节输出流类型,所以需要传递一个字节输出流的实现类对象(比如FileOutputStream文件输出流对象)和一个编码方式(默认为utf-8)。
使用平台默认字符集
package org.westos.demo2;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* @author lwj
* @date 2020/5/25 19:01
*/
public class MyTest {
public static void main(String[] args) {
//输出流所关联的文件如果不存在,会自动创建
//字符流包装了字节流
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(new FileOutputStream(
new File("src\\org\\westos\\demo2\\a.txt"), true), StandardCharsets.UTF_8);
//FileOutputStream字节输出流的构造方法,一个File,一个append是否允许追加
//OutputStreamWriter字符输出流的构造方法,一个FileOutputStream,一个编码方式(把字符串按照某种编码方式转换为字节数组)
osw.write('我');
//write(int c) 写入一个字符
osw.write("\r\n");
osw.write("爱奇艺会员");
//write(String s) 写入一个字符串
osw.write("\r\n你有吗?".toCharArray());
//write(char[] ch) 写入一个字符数组
osw.write("\r\n");
osw.write("麻烦借我一下好吗", 2, 4);
//write(String s, int off, int len) 写入字符串的一部分
osw.write("\r\n");
osw.write("谢谢".toCharArray(), 0, 2);
//write(char[] ch, int off, int len) 写入字符数组的一部分
osw.flush();
//输出流记得flush
} catch (IOException e) {
e.printStackTrace();
} finally {
if (osw != null) {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
a.txt文件
我
爱奇艺会员
你有吗?
麻烦借我一下
谢谢
使用GBK字符集
package org.westos.demo2;
import java.io.*;
/**
* @author lwj
* @date 2020/5/25 19:40
*/
public class MyTest2 {
public static void main(String[] args) {
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(new FileOutputStream(
new File("src\\org\\westos\\demo2\\b.txt"), true), "GBK");
//使用GBK编码方式的字符流
osw.write("我是GBK类型的文件");
osw.write("\r\n");
osw.write("文件类型必须转为GBK才可以查看文件".toCharArray());
osw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (osw != null) {
osw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
InputStreamReader
public class InputStreamReader extends Reader { }
构造方法
InputStreamReader(InputStream in)
//使用默认编码读取数据
InputStreamReader(InputStream in, String charsetName)
InputStreamReader(InputStream in, Charset cs)
//使用指定编码读取数据
输入字符流。
使用平台默认字符集
c.txt
acbdefgABCDEFG爱上对方过后就卡了
package org.westos.demo3;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* @author lwj
* @date 2020/5/25 20:08
*/
public class MyTest {
public static void main(String[] args) {
InputStreamReader isr = null;
try {
isr = new InputStreamReader(new FileInputStream(new File(
"src\\org\\westos\\demo3\\c.txt")), StandardCharsets.UTF_8);
//字符输入流InputStreamReader
//字节输入流的文件如果不存在会报错
int read = isr.read();
//read() 读取一个字符
System.out.println((char) read);
char[] chars = new char[5];
int len = 0;
while ((len = isr.read(chars)) != -1) {
//read(char[] chars) 读取一个字符数组
System.out.println(new String(chars, 0, len));
//new String(char[], int offset, int len)
}
/*
a
cbdef
gABCD
EFG爱上
对方过后就
卡了
*/
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (isr != null) {
isr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
使用GBK字符集
d.txt
我是GBK类型的文件,必须用GBK解码的字符流才可以读取。
package org.westos.demo3;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author lwj
* @date 2020/5/26 15:22
*/
public class MyTest2 {
public static void main(String[] args) {
InputStreamReader isr = null;
try {
isr = new InputStreamReader(new FileInputStream(new File(
"src\\org\\westos\\demo3\\d.txt")), "GBK");
//读取b.txt文件,GBK解码
char[] chars = new char[5];
int len = 0;
while ((len = isr.read(chars)) != -1) {
System.out.println(new String(chars, 0, len));
}
/*
我是GBK
类型的文件
,必须用G
BK解码的
字符流才可
以读取。
*/
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (isr != null) {
isr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流复制文本文件
复制平台默认编码的文件
我们复制一个Java文件。
package org.westos.demo4;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* 字符流复制文本文件
* @author lwj
* @date 2020/5/26 15:42
*/
public class MyDemo {
public static void main(String[] args) {
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
isr = new InputStreamReader(new FileInputStream(
new File("src\\org\\westos\\demo\\MyTest.java")), StandardCharsets.UTF_8);
//使用平台默认的编码方式解码
osw = new OutputStreamWriter(new FileOutputStream(
new File("src\\org\\westos\\demo4\\MyTest.java"), true), StandardCharsets.UTF_8);
//使用平台默认的编码方式编码
char[] chars = new char[10];
int index = 0;
int len = 0;
while ((len = isr.read(chars)) != -1) {
index++;
osw.write(chars, 0, len);
osw.flush();
}
System.out.println(index);
//63
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (isr != null) {
isr.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (osw != null) {
osw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
复制GBK编码的文件
package org.westos.demo4;
import java.io.*;
import java.nio.charset.StandardCharsets;
/**
* @author lwj
* @date 2020/5/26 17:47
*/
public class MyDemo2 {
public static void main(String[] args) {
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
isr = new InputStreamReader(new FileInputStream(
new File("src\\org\\westos\\demo2\\b.txt")), "GBK");
//用GBK解码
osw = new OutputStreamWriter(new FileOutputStream(
new File("src\\org\\westos\\demo4\\e.txt")), StandardCharsets.UTF_8);
//用UTF-8编码
char[] chars = new char[20];
int len = 0;
while ((len = isr.read(chars)) != -1) {
osw.write(chars, 0, len);
osw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (isr != null) {
isr.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (osw != null) {
osw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
FileWriter和FileReader
字符流OutputStreamWriter和InputStreamReader的名称太长,所以提供了一个他们的子类。(字符流便捷类)
public class FileReader extends InputStreamReader {}
public class FileWriter extends OutputStreamWriter {}
构造方法
FileReader(File file)
//按照默认的编码方式解码
FileWriter(File file)
//按照默认的编码方式编码
FileWriter(File file, boolean append)
//按照默认的编码方式编码,并且允许文件追加
便捷字符流类:
缺点:只能使用平台默认编码;
使用便捷字符流类复制文件
package org.westos.demo5;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* FileReader和FileWriter
* @author lwj
* @date 2020/5/26 17:40
*/
public class MyTest {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(new File("src\\org\\westos\\demo2\\a.txt"));
//使用平台默认编码进行解码
fw = new FileWriter(new File("src\\org\\westos\\demo5\\f.txt"), true);
char[] chars = new char[10];
int len = 0;
while ((len = fr.read(chars)) != -1) {
fw.write(chars, 0, len);
fw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fw != null) {
fw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
BufferedWriter和BufferedReader
缓冲字符流
public class BufferedWriter extends Writer {}
public class BufferedReader extends Reader {}
构造方法
BufferedWriter(Writer out)
BufferedReader(Reader in)
使用缓冲字符流类复制文件
package org.westos.demo5;
import java.io.*;
/**
* 字符缓冲流
* @author lwj
* @date 2020/5/26 18:26
*/
public class MyTest2 {
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(new File("src\\org\\westos\\demo2\\a.txt")));
//new FileReader / new InputStreamReader
bw = new BufferedWriter(new FileWriter(new File("src\\org\\westos\\demo5\\g.txt"), true));
//new FileWriter / new OutputStreamWriter
String s = null;
while ((s = br.readLine()) != null) {
//BufferReader的readLine()方法读取一行数据,如果读取不到返回null
bw.write(s);
//写入字符串
bw.newLine();
//写入一个行分隔符,具有平台兼容性
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
练习
把集合中的数据存储到文本文件
package org.westos.test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author lwj
* @date 2020/5/26 19:58
*/
public class MyTest {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("第一个出场");
strings.add("不是因为lady优先");
strings.add("是因为我带着冠军制作人的头衔");
strings.add("没人能阻挡 全部待在我的后面");
strings.add("台上有我 其他人根本无法露面");
strings.add("I am the champion");
strings.add("举手投足");
strings.add("Shine bright like a gem");
strings.add("比任何人都出彩");
strings.add("摘下过去头顶那些光环");
strings.add("来日的胜利却会更壮观");
strings.add("即使夜再漆黑 我再疲惫");
strings.add("对我打击微乎其微 累不气馁");
strings.add("无愧美誉地位 我踏实地每步积累");
strings.add("自古以来真正厉害的偶像");
strings.add("无反顾带领新一代的走向");
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(new File("src\\org\\westos\\test\\gem.txt"), true));
//BufferedWriter的构造方法参数是一个Writer
for (String string : strings) {
writer.write(string);
writer.newLine();
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
把文本文件中的数据存储到集合中
package org.westos.test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
/**
* @author lwj
* @date 2020/5/26 20:21
*/
public class MyTest2 {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(new File("src\\org\\westos\\test\\gem.txt")));
//BufferedReader(Reader)
//FileReader使用平台默认字符集解码
String s = null;
while ((s = reader.readLine()) != null) {
strings.add(s);
}
for (String string : strings) {
System.out.println(string);
}
/*
第一个出场
不是因为lady优先
是因为我带着冠军制作人的头衔
没人能阻挡 全部待在我的后面
台上有我 其他人根本无法露面
I am the champion
举手投足
Shine bright like a gem
比任何人都出彩
摘下过去头顶那些光环
来日的胜利却会更壮观
即使夜再漆黑 我再疲惫
对我打击微乎其微 累不气馁
无愧美誉地位 我踏实地每步积累
自古以来真正厉害的偶像
无反顾带领新一代的走向
*/
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
复制指定目录下指定后缀名的文件并改名
package org.westos.test;
import java.io.*;
/**
* @author lwj
* @date 2020/5/26 20:36
*/
public class MyDemo {
public static void main(String[] args) {
File source = new File("src\\org\\westos\\test2");
File dest = new File("src\\org\\westos\\test3");
if (!dest.exists()) {
dest.mkdir();
}
File[] sourceFiles = source.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir, name).isFile() && name.endsWith(".java");
}
});
for (File sourceFile : sourceFiles) {
String name = sourceFile.getName();
name = name.replace(".java", ".jad");
copyFile(sourceFile, new File(dest, name));
}
}
public static void copyFile(File source, File dest) {
BufferedWriter writer = null;
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(source));
writer = new BufferedWriter(new FileWriter(dest, true));
String s = null;
while ((s = reader.readLine()) != null) {
writer.write(s);
writer.newLine();
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
键盘录入学生信息按照总分排序并写入文本文件
package org.westos.test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
/**
* @author lwj
* @date 2020/5/26 20:54
*/
public class MyDemo2 {
public static void main(String[] args) throws IOException {
ArrayList<Student> students = new ArrayList<>();
Scanner sc = new Scanner(System.in);
int index = 0;
while (index < 3) {
System.out.println("请输入学生姓名,语文成绩,数学成绩和英语成绩,之间用空格分隔:(张三 80 80 80)");
String name = sc.next();
int chineseScore = sc.nextInt();
int mathScore = sc.nextInt();
int englishScore = sc.nextInt();
students.add(new Student(name, chineseScore, mathScore, englishScore));
index++;
}
//使用Collections.sort(list, Comparator)或者ArrayList的sort方法
students.sort(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return -Integer.compare(o1.getTotalScore(), o2.getTotalScore());
//按照总分从高到低
}
});
BufferedWriter writer = new BufferedWriter(new FileWriter(
new File("src\\org\\westos\\test\\student.txt"), true));
for (Student student : students) {
writer.write(student.toString());
writer.newLine();
writer.flush();
}
}
}