import org.junit.jupiter.api.Test;
import java.io.*;
import java.util.Arrays;
//@SpringBootTest
class SpringbootClangApplicationTests {
/** # FileOutputStream(字节输出流)
* 输出到文件
* 一.创建字符流对象
*
* 二.写出数据
*
* 三.释放资源
* 1.void write(int b) 一次写一个字节
* 2.void write(byte[] b) 一次写一个字节数组数据
* 3.void write(byte[] b, int off, int len) 一次写入部分数据
* ## 注意事项
* 默认覆盖之前的内容
* public FileOutputStream(File file, boolean append)
* 通过FileOutputStream(filePath, true) 追加写入
*/
// 1.void write(int b)
@Test
void testIntB() throws IOException {
//1.创建输出流
FileOutputStream fos = new FileOutputStream("a.txt");
//2.写入数据
fos.write('a');
//3.关闭资源
fos.close();
}
// 2.void write(byte[] b)
@Test
void testByteB() throws IOException {
//1.创建对象
FileOutputStream fos = new FileOutputStream("a.txt");
//2.创建字节数组
byte[] bytes = {97, 98, 99, 100, 101};
//3. 写入数据
fos.write(bytes);
//4.关闭资源
fos.close();
}
//3.void write(byte[] b, int off, int len)
/**
* 参数一、数组
* 参数二、起始位置
* 参数三、个数
* @throws IOException
*/
@Test
void testStringB() throws IOException {
//1.创建对象
FileOutputStream fos = new FileOutputStream("a.txt");
// 0 1 2 3 4
//2.创建数组 a b c d e
byte[] bytes = {97, 98, 99, 100, 101};
fos.write(bytes, 1, 2);
//3.关闭资源
fos.close();
}
//案例
@Test
public void demo() throws IOException {
//1.创建对象
FileOutputStream fos = new FileOutputStream("a.txt");
//2.写出数据
String str = "abc";
byte[] bytes = str.getBytes();
fos.write(bytes);
// fos.write('\n');
// fos.write('\r');
String str2 = "def";
byte[] bytes2 = str2.getBytes();
fos.write(bytes2);
//3.释放资源
fos.close();
}
/** # FielInputStream(字节输入流)
* 读取文件的数据
* ## 实现步骤
* 1.创建对象
* 2.读取数据
* 3.释放资源
* ## 注意事项
* 1.如果文件不存在,会直接报错
* 2.如果读到文件末尾,值为-1
*/
@Test
public void fileInputDemo() throws IOException {
//1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
//2.读取数据
int b1 = fis.read();
System.out.println(b1);
int b2 = fis.read();
System.out.println(b2);
int b3 = fis.read();
System.out.println(b3);
int b4 = fis.read();
System.out.println(b4);
int b5 = fis.read();
System.out.println(b5);
}
/**
* 循环读取字节输入流
* read读取一次数据,就移动一次指针
*/
@Test
public void fileInputDemo02() throws IOException {
//1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
//2.循环读取
int b=0;
while ((fis.read()) !=-1){
System.out.println((char)b);
}
//3.释放资源
fis.close();
}
/**
* FileInputStream
* public int read() 一次读一个字节
* public int read(byte[] buffer) 一次读一个字节数组(尽可能把数组填满)
*/
/**
* # 实战一
* 小文件拷贝
*
*/
@Test
public void fileInputDemo03() throws IOException {
//1.创建对象
FileInputStream fis = new FileInputStream("grim.png");
FileOutputStream fos = new FileOutputStream("copy.png");
//2.拷贝
//核心思想,边读边写
int b;
while ((b = fis.read()) !=-1){
fos.write(b);
}
//3.释放资源
//规则,先开的后关闭
fos.close();
fis.close();
}
/**
* # 实战
* 大文件拷贝
* 主要事项
* 尽可能装满数组
* 读不到数据就返回-1
*/
@Test
public void fileInputDemo04() throws IOException {
//1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
//2.读取数据
byte[] bytes = new byte[2];
//一次读取多少字节数据,由数组长度决定
//返回值,本次读到多少个字节数据
//第一次读
int len1 = fis.read(bytes);
System.out.println(len1);
String str = new String(bytes,0,len1);
System.out.println(str); //ab
//第二次读
int len2 = fis.read(bytes);
String str2 = new String(bytes,0,len2);
System.out.println(str2); //cd
//第三次读
int len3 = fis.read(bytes);
// String str3 = new String(bytes,0,len3);
String str3 = new String(bytes); //e->c->(ed)
System.out.println(str3);
// //第四次读
// int len4 = fis.read(bytes);
// String str4 = new String(bytes,0,len4);
// System.out.println(str4);
//3.释放资源
fis.close();
}
/**
* 文件拷贝改写
*
*/
@Test
public void fileCopy() throws IOException {
/**
* 异常处理
* try {
* 1.创建对象
* 2.处理数据
* } catch() {
* 异常处理代码
* } finally {
* 3.关闭资源
* }
*/
/**
* 简化后
*/
//1.创建对象
try(FileInputStream fis = new FileInputStream("grim.png");
FileOutputStream fos = new FileOutputStream("copy.png")) {
//2.读取数据
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} //3.释放资源。自动执行了finay 关闭了资源
}
/**
* 字符集
* 一、ASCII
* 一字节,前面补0,补齐8位
* a->97->0110 0001
*
* 二、GBK(GB扩展)
* 存储英文:兼容ASCII
* 存储中文:二字节(高位和低位),以1开头
*
* 三、Unicode
* 一个英文占1字节,第一位是0,转成数字是一个正数
* 一个汉字占3字节,第一个字节的第一位是1,转成数字是一个负数
* UTF-8一种编码方式(不是字符集)
* 0xxxxxxx(ASCII)
* 110xxxxx 10xxxxxx
* 1110xxxx 10xxxxxx 10xxxxxx(使用Unicode 填补)
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*
* 四、为什么有乱码?
* 1.字节流读取未读完整个汉字
* 2.使用不同方式编码和解码
*
* 五、为什么字节流读取时会产生乱码,而拷贝时不会?
* 拷贝到目的地数据没有丢失,使用对应编码方式读不会产生乱码。
*
*/
/**
* Java中编码的方法
* public byte[] getBytes() 使用默认方式进行编码
* public byte[] getBytes(String charsetName) 使用指定方式进行编码
*
* Java中解码的方法
* String(byte[] bytes) 使用默认方式进行解码
* String(byte[] bytes, String charsetName) 使用指定方式进行解码
*/
@Test
public void charsetNameDemo() throws UnsupportedEncodingException {
//1.编码
String str = "ai你哟";
byte[] bytes1 = str.getBytes("GBK");
byte[] bytes2 = str.getBytes("UTF-8");
System.out.println(Arrays.toString(bytes1));
System.out.println(Arrays.toString(bytes2));
//2.解码
String str1 = new String(bytes1);
System.out.println("GBK:"+str1);
String str2 = new String(bytes2);
System.out.println("UTF-8:"+str2);
}
/**
* 字符流读取
* 本质上就是字节流+字符集
* 1.创建字符流对象
* 2.读取数据读到末尾返回-1
* 3.释放资源
*/
//一、字符流默认一次读一个字节
@Test
public void fileReaderDemo() throws IOException {
//1.创建对象并关联本地文件
FileReader fr = new FileReader("a.txt");
//2.读取数据 read()
//字符流的底层就是字节流,默认按照一个字节一个字节读取的
//如果遇到中文1就会异常读取多个,GBK一次读2字节,UTF-8一次读3字节
//最终返回一个10进制
int ch;
while ((ch = fr.read()) != -1) {
System.out.println(ch);
}
//3.释放资源
fr.close();
}
//二、字符流默认一次读多个字节
@Test
public void fileReaderBytes() throws IOException {
//1.创建对象
FileReader fr = new FileReader("a.txt");
//2.读取数据,一次默认读两个字符
char[] chars = new char[2];
int len;
//read(char) 把读取数据、解码、强转 三步合并了,放到字符数字中
while ((len = fr.read(chars)) != -1) {
//可能读不满
System.out.println(new String(chars, 0, len));
}
//3.释放资源
fr.close();
}
/**
* TODO 字符输出流
* 1.创建字符流对象
* public FileWriter(File file)
* public FileWriter(String pathname)
* public FileWriter(File file, boolean append) 续写
* public FileWriter(String pathname, boolean append) 续写
* 2.读取数据
* void write(int c) 写一个字符
* void write(String str) 写出一个字符串(主要)
* void write(char[] cbuf) 写出一个字符数组
* void write(char[] cbuf, int off, int len) 写出字符数组的一部分
*
* 3.关闭资源
* @throws IOException
*/
//TODO 字符输出流 写一个字符
@Test
public void fileWriterDemo() throws IOException {
//1.创建对象,关联本地文件
FileWriter fw = new FileWriter("a.txt");
//2.写入数据
fw.write(25105); //根据字符集进行编码,把编码后的数据写入到文件中
//3.关闭字符输出流
fw.close();
}
// TODO 字符输出流 写一个字符串
@Test
public void fileWriterStrDemo() throws IOException {
//1.创建对象
FileWriter fw = new FileWriter("a.txt");
//2.写入数据
fw.write("我是你爹");
//3.关闭资源
fw.close();
}
/**
* 字符流原理
* FileReader
* 会创建一个8192字节的缓冲区
* 把数据放到缓冲区中读,尽可能填满缓冲区
* 每次read() 都会判断缓冲区是否有内容
* 如果缓冲区用完了
* 就会继续从文件中取到缓冲区
* 如果文件也没有内容,就会返回-1
* 如果缓冲区满了,就会
* FileWriter
* 创建一个缓冲区
* 每次write()会写到缓冲区
* 当
* 1.缓冲区满了会自动保存
* 2.flush后
* 3.关闭资源前,会检查缓冲区中是否有数据
* 时,会把缓冲区的数据写出到文件中
*/
/**
* 实战一
* 拷贝文件夹
* 判断是否是文件
* 是: 进行拷贝
* 不是:继续遍历
*/
@Test
public void StreamDemo() throws IOException {
//拷贝一个文件夹,考虑子文件夹
//1.创建对象表示数据源
File src = new File("/home/ime/Documents/hello");
// File[] files = src.listFiles("demo/a.txt");
//2.创建对象表示目的地
File dest = new File("demo/hello");
//3.调用方法进行拷贝
copydir(src, dest);
}
public void copydir(File src, File dest) throws IOException {
//递归
//1.进入数据源
File[] files = src.listFiles();
if(files==null) return;
//2.便利数组
for(File file : files){
//判断文件
if(file.isFile()) {
//3.开始拷贝
FileInputStream fis = new FileInputStream(file);//要拷贝的文件
FileOutputStream fos = new FileOutputStream(dest + "/" + file.getName());//拷贝的目的地
byte[] b = new byte[1024];
int len;
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
fos.close();
fis.close();
} else {
//4.如果是文件夹.递归
copydir(file, new File(dest, file.getName()));
}
}
}
/**
* 实战二
* 文件加密
*/
@Test
public void StreamDemo02() throws IOException {
//1.创建对象关联原始文件
FileInputStream fis = new FileInputStream("a.txt");
//2.创建对象关联加密文件
FileOutputStream fos = new FileOutputStream("ency.txt");
//3.加密处理
int b;
while ((b = fis.read())!= -1) {
fos.write(b^2);
}
//4.释放资源
fos.close();
fis.close();
}
@Test
public void StreamDemo03() throws IOException {
FileReader fis = new FileReader("a.txt");
FileWriter fos = new FileWriter("demo/ency.txt");
char[] chars = new char[2];
int len;
while ((len = fis.read(chars)) != -1) {
fos.write(chars, 0, len);
}
}
}