如何不产生乱码
1.不要使用字节流读取文本文件
2.编码解码时使用同一个码表,同一个编码方式
字符流
字符流的底层就是字节流。
特点:
输入流:一次读一个字节遇到中文时,一次读多个字节。
输出流:底层会把数据按照指定的编码方式进行编码,变成字节在写到文件中。
使用场景:对于纯文本文件进行读写操作。
FileReader
步骤:
1.创建字符输入对象
细节:读取的文件不存在,就会直接报错
2.读取数据
细节1:按字节进行读取,遇到中文,一次读取多个字节,读取后解码,返回一个整数。
细节2:读到文件末尾了,read方法返回-1.
3.释放资源
java
package MyCharset;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CharSetDemo01 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("F:\\javaEE\\src\\MyCharset\\c.txt");
int ch;
while((ch=fr.read())!=-1){
System.out.print((char) ch);
}
fr.close();
}
}
java
package MyCharset;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CharSetDemo02 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("F:\\javaEE\\src\\MyCharset\\c.txt");
char[] c=new char[2];
int len;
while((len=fr.read(c))!=-1) {
System.out.println(c);
}
fr.close();
}
}
FileWriter
步骤:
1.创建字符输出流对象
细节1:参数是字符串表示的路径或者File对象都是可以的
细节2:如果文件不存在则会创建一个新的文件,但是要保证父级路径存在
细节3:如果文件已经存在,则会清空文件,如果不想清空可以打开续写开关
2.写数据
细节:如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符
3.释放资源
java
package MyCharset;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CharSetDemo03 {
public static void main(String[] args) throws IOException {
FileWriter fw=new FileWriter("F:\\javaEE\\src\\MyCharset\\c.txt");
fw.write("karry");
// fw.close();
char[] chars={'a','b','c','我'};
fw.write(chars);
fw.close();
}
}
字符流原理解析
字符输入流底层原理
1.创建字符输入流对象
底层:关联文件,并创建缓冲区(长度为8192的字节数组)
2.读取数据
底层:1.判断缓冲区是否有数据可以读取
2.缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区,如果文件中也没有数据了,返回-1.
3.缓冲区有数据:就从缓冲区中读取
空参的read方法:一次读取一个字节,遇到中文一次读取多个字节,把字节解码并转成十进制返回。
有参的read方法:把读取字节、解码、强转三步合并了,强转之后的字符放到数组中。
综合练习
拷贝:拷贝一个文件夹需要考虑子文件夹
java
package MyCharset;
import java.io.*;
public class Test01 {
public static void main(String[] args) throws IOException {
// 1.创建一个对象表示数据源
File src=new File("D:\\aaa\\src");
//2.创建对象表示目的地
File dest=new File("D:\\aaa\\dest");
//3.调用方法进行拷贝
copydir(src,dest) ;
}
private static void copydir(File src, File dest) throws IOException {
//递归
dest.mkdirs();
File[] files = src.listFiles();
for (File file : files) {
if(file.isFile()){
FileInputStream fis=new FileInputStream(file);
FileOutputStream fos=new FileOutputStream(new File(dest,file.getName()));
byte[] bytes=new byte[1024];
int len;
while((len=fis.read(bytes))!=-1){
fos.write(bytes,0,len);
}
fos.close();
fis.close();
}else{
copydir(file,new File(dest,file.getName()));
}
}
}
}
文件加密:
为了保证文件的安全性,就需要对原始文件进行加密存储,再使用的时候在对其解密处理。
加密原理:对原始文件中的每一个字节数据进行更改,然后将更改后的数据存储到新的文件中。
解密原理:读取加密后的文件,按照加密的规则反向操作,变成原始文件。
java
package MyCharset;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test2 {
public static void main(String[] args) throws IOException {
FileInputStream fis=new FileInputStream("myio\\girl.jpg");
FileOutputStream fos=new FileOutputStream("myio\\ency.jpg");
int b;
while((b=fis.read())!=-1){
fos.write(b^2);
}
fos.close();
fis.close();
}
}
修改文件中的数据
java
package MyCharset;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
public class Test3 {
public static void main(String[] args) throws IOException {
FileReader fr=new FileReader("F:\\javaEE\\src\\MyCharset\\a.txt");
StringBuilder sb=new StringBuilder();
int ch;
while((ch=fr.read())!=-1){
sb.append((char)ch);
}
fr.close();
System.out.println(sb);
String str=sb.toString();
String[] arrstr = str.split("-");
ArrayList<Integer> list=new ArrayList<>();
for (String s : arrstr) {
int i= Integer.parseInt(s);
list.add(i);
}
Collections.sort(list);
System.out.println(list);
FileWriter fw=new FileWriter("F:\\javaEE\\src\\MyCharset\\a.txt");
for (int i = 0; i < list.size(); i++) {
if(i==list.size()-1){
fw.write(list.get(i)+"");
}else{
fw.write(list.get(i)+"-");
}
}
fw.close();
}
}
利用字节缓冲流拷贝文件
java
package MyCharset;
import java.io.*;
public class Test4 {
public static void main(String[] args) throws IOException {
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("F:\\javaEE\\src\\MyCharset\\a.txt"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("F:\\javaEE\\src\\MyCharset\\copy.txt"));
int b;
while((b=bis.read())!=-1){
bos.write(b);
}
bos.close();
bis.close();
}
}
java
package MyCharset;
import java.io.*;
public class Test5 {
public static void main(String[] args) throws IOException {
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("F:\\javaEE\\src\\MyCharset\\a.txt"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("F:\\javaEE\\src\\MyCharset\\copy.txt"));
byte[] bytes=new byte[1024];
int len;
while((len=bis.read())!=-1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
}
}