Java之字符流 day12
💞为什么出现字符流?
字符流=字节流+编码表
- 用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,
- 如何识别时中文呢?
- 汉字在存储的时候,无论选择哪一种编码存储,第一个字节都是负数
- utf-8:一个中文占3个字节
- GBK:一个中文占2个字节
💞字符串中的编码解码问题
- 编码:byte[] getBytes(String charsetName)
public class Characterstream01 {
public static void main(String[] args) throws UnsupportedEncodingException {
//字符串中的编码解码问题
/*byte[] getBytes():使用平台的默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
*byte[] getBytes(String charsetName):使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
*/
//编码:默认、utf-8、GBK
String s="中国";
//byte[] bytes=s.getBytes();//[-28, -72, -83, -27, -101, -67]
//byte[] bytes = s.getBytes(StandardCharsets.UTF_8);//[-28, -72, -83, -27, -101, -67]
byte[] bytes = s.getBytes("GBK");//[-42, -48, -71, -6]
System.out.println(Arrays.toString(bytes));
//归根字符编码=字节流+编码方式
}
}
- 解码:String(byte[] bytes,String charsetName)
public class Characterstream01 {
public static void main(String[] args) throws UnsupportedEncodingException {
String s="中国";
byte[] bytes = s.getBytes();
//解码
//String(byte[] bytes):通过适用平台的默认字符集解码指定的字节数组来构造新的String
//String(byte[] bytes,String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
//解码:默认、utf-8、GBK
String ss=new String(bytes,"GBK");
System.out.println(ss);//中国 默认解码 默认编码 //中国 默认解码 urf-8编码
//用默认解码,GBK编码结果:�й� 不行
/*
* 结论:用什么编码就用什么解码
* */
}
}
结论:用什么编码方式,解码就用什么解码方式
🎈OutputStreamWriter/InputStreamWriter:
是从字符流到字节流的桥接
:使用指定的字符集将写入其中的字符编码为字节
。它使用的字符集可以通过名称指定,也可以明确指定,或者可以接受平台的默认字符集。
public class Characterstream02 {
public static void main(String[] args) throws IOException {
//OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("src\\\\Demo\\\\Characterstream\\\\Stream.txt")) ;
//OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("src\\Demo\\Characterstream\\Stream.txt"),"utf-8");
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("src\\Demo\\Characterstream\\Stream.txt"),"GBK");
//GBK编码不行:�й� 必须使用同GBK进行编码才行
osw.write("中国");
osw.close();
InputStreamReader read=new InputStreamReader(new FileInputStream("src\\Demo\\Characterstream\\Stream.txt"),"GBK");
int by;
while((by=read.read())!=-1){
System.out.print((char)by);//中国
}
}
}
🎈字符流写数据的五种方式
方法名 | 说明 |
---|---|
void write(int c) | 写一个字符 |
void write(char[] cbuf) | 写一个字符数组 |
void write(char[] cbuf,int off,int len) | 写一个字符数组的一个部分 |
void write(String str) | 写一个字符串 |
void write(String str,int off ,int len) | 写一个字符串的一部分 |
方式一:void write(int c)
public Characterstream03() throws IOException {
//OutputStreamWriter(OutputStream out)创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter os=new OutputStreamWriter(new FileOutputStream("src\\com\\week\\day03\\Demo.txt"));
//方法一,字符的写入
os.write(97);
os.flush();//刷新流(不刷新文件内无法显示,会被存储在缓存中)
os.write(98);
os.flush();
os.write(99);
os.close();//关闭并刷新,关闭之后则stream就会关闭
}
}
方法二:void write(char[] cbuf)
public Characterstream03() throws IOException {
//OutputStreamWriter(OutputStream out)创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter os=new OutputStreamWriter(new FileOutputStream("src\\com\\week\\day03\\Demo.txt"));
//方法二,字符的写入
char[] bs={'a','b','c','d','f'};
os.write(bs);
os.close();
}
}
方法三:void write(char[] cbuf,int off,int len)
public Characterstream03() throws IOException {
//OutputStreamWriter(OutputStream out)创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter os=new OutputStreamWriter(new FileOutputStream("src\\com\\week\\day03\\Demo.txt"));
//方法三、写入字符数组的一部分
char[] bs={'a','b','c','c','f'};
os.write(bs,0,2);
os.close();
}
}
方法四:void write(String str)
public Characterstream03() throws IOException {
//OutputStreamWriter(OutputStream out)创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter os=new OutputStreamWriter(new FileOutputStream("src\\com\\week\\day03\\Demo.txt"));
//方法四:写入字符串
os.write("好家伙!");
os.close();
}
}
方法五:void write(String str,int off ,int len)
public Characterstream03() throws IOException {
//OutputStreamWriter(OutputStream out)创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter os=new OutputStreamWriter(new FileOutputStream("src\\com\\week\\day03\\Demo.txt"));
//方法五;写入字符串一部分
os.write("abcdgssfs",2,3);
os.close();//关闭并刷新,关闭之后则stream就会关闭
}
}
🎈字符流读数据的两种方式
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
方法一:int read()
public class Characterstream04 {
public static void main(String[] args) throws IOException {
InputStreamReader read=new InputStreamReader(new FileInputStream("src\\Demo\\Characterstream\\Stream.txt"));
//读取方法一 一字符读取
int num;
while((num=read.read())!=-1){
System.out.print((char)num);
}
}
}
方法二:int read(char[] cbuf)
public class Characterstream04 {
public static void main(String[] args) throws IOException {
InputStreamReader read=new InputStreamReader(new FileInputStream("src\\Demo\\Characterstream\\Stream.txt"));
//读取方法二:一数组字符读取
int num;
char [] bys=new char[1024];
while((num=read.read(bys))!=-1){
System.out.print(new String(bys,0,num));
}
}
}
🎈案例:复制java文件
方法一:
public class Stream01 {
/*
* 复制HelloWorld.java文件
* 1、创建读取流读取
* 2、创建输入流写入
* 3、释放资源
* */
public static void main(String[] args) throws IOException {
//创建读取流
InputStreamReader read=new InputStreamReader(new FileInputStream("src\\Demo\\Characterstream\\HelloWorld.java"));
//创建写入流
OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream("src\\Demo\\Characterstream\\HelloWorld01.java"));
int num;
char [] ch=new char[1024];
while((num=read.read(ch))!=-1){
writer.write(ch,0,num);
}
read.close();
writer.close();
}
}
方案二:FileWriter()和FileReader()
public class Stream01 {
/*
* 复制HelloWorld.java文件
* 1、创建读取流读取
* 2、创建输入流写入
* 3、释放资源
* */
public static void main(String[] args) throws IOException {
//创建读取流
FileReader read=new FileReader("src\\Demo\\Characterstream\\HelloWorld.java");
//创建写入流
FileWriter writer=new FileWriter("src\\Demo\\Characterstream\\HelloWorld01.java");
int num;
char [] ch=new char[1024];
while((num=read.read(ch))!=-1){
writer.write(ch,0,num);
}
read.close();
writer.close();
}
}
注意:FileReader()/FileWriter():与其父类一样,有两种读数据方法结果一样,但如果要研究字节流转字符流,则需要用其父类
🎈字符流缓冲流
- BufferedWriter:将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
- BufferedReader:从字符输入流读取文本,缓冲字符,以提供单个字符,数组和字符串的高效写入。
构造方法:
- BufferedWriter(Writer out)
- BufferedReader(Reader in)其内部封装了一个8192的数组
🎉BufferedWriter(Writer out)缓冲写入
public static void main(String[] args) throws IOException {
BufferedWriter bw=new BufferedWriter(new FileWriter("src\\Demo\\Characterstream\\Buffer.txt"));
bw.write("hello\r\n");
bw.write("world");
bw.close();
}
🎉BufferedReader(Reader in)缓冲读取
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new FileReader("src\\Demo\\Characterstream\\Buffer.txt"));
//字符读取
// int num;
// while((num=br.read())!=-1){
// System.out.print((char)num);
// }
//字符数组
int num;
char [] ch=new char[1024];
while((num=br.read(ch))!=-1){
System.out.println(new String(ch,0,num));
}
br.close();
}
}
🎉字符缓冲流的特有功能(void newLine():写一个行分隔符)
public class BufferedStream01 {
/*
* 字符缓冲流的特有功能
* BufferedWriter:
* 1、void newLine():写一个行分隔符,可以因系统不同变化对应的分隔符
* */
public static void main(String[] args) throws IOException {
//1、void newLine():写一个行分隔符,可以因系统不同变化对应的分隔符
BufferedWriter bw=new BufferedWriter(new FileWriter("src\\Demo\\Characterstream\\Buffer.txt"));
for (int i = 0; i <10 ; i++) {
bw.write("hello world");
bw.newLine();//换行
bw.flush();//刷新
}
bw.close();
}
}
🎉 字符缓冲流的特有功能(public String readLine():读一行文字)
public class BufferedStream01 {
/*
* 字符缓冲流的特有功能
* BufferedReader:
* 1、public String readLine():读一行文字,不包含什么换行符,终止符,到达末尾则为null
* */
public static void main(String[] args) throws IOException {
// 1、public String readLine():读一行文字,不包含什么换行符,终止符,到达末尾则为null
BufferedReader br=new BufferedReader(new FileReader("src\\Demo\\Characterstream\\Buffer.txt\\"));
for (int i = 0; i < 10; i++) {
System.out.println(br.readLine());
}
System.out.println(br.readLine());
br.close();
}
}
结论:如果输出null则是已经到文章末尾了
✨总结出最常用的都文档方式
public class BufferedStream02 {
/*
* 最常用的文件读写方式
* */
public static void main(String[] args) throws IOException {
//读取数据
BufferedReader br=new BufferedReader(new FileReader("src\\Demo\\当时光老了.txt"));
//写数据
BufferedWriter bw=new BufferedWriter(new FileWriter("src\\Demo\\当时光老了备份.txt"));
String lin;
while((lin=br.readLine())!=null){
bw.write(lin);
bw.newLine();//换行
bw.flush();//刷新
}
br.close();
bw.close();
}
}