初识IO流:
一、概念
存储和读取数据的解决方案
二、作用
用于读写数据(本地文件,网络)
三、按流向分:
输出流-把程序写出到本地文件中
输入流-把文件中的数据读取到程序中
四、按操作文件的类型可以分:
字节流:可以操作所有类型的文件
字符流:只能操作纯文本文件
五、什么是纯文本文件?
用windows系统自带的记事本打开并且能读懂的文件(txt,md,lrc,xml等)
IO流的体系结构:
字节输出流:
public class demo01 {
public static void main(String[] args) throws IOException {
/*字节输出流的细节:
1.创建字节输出流对象
细节一:参数是字符串表示的路径或者是File对象都是可以的
细节二:如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的
细节三:如果文件已经存在,则会清空文件
2.写数据
细节:write方法的参数都是整数,但是实际写到本地文件的整数是ASCII上对应的字符
如果要打印97,则输入字符'9'和字符'7'的ASCII值
3.释放资源
每次使用完流之后都要释放资源
*/
//1.创建对象
FileOutputStream fos=new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\a.txt");
//2.写出数据
fos.write(97);
//3.释放资源
fos.close();
}
}
FileOutStream写数据的两个小问题:
1.换行写
2.续写
public class demo02 {
public static void main(String[] args) throws IOException {
/* 换行写
直接在中间输出一个换行符\r\n即可
续写
在创建文件的时候把续写开关打开即可
*/
//1.创建对象
FileOutputStream fos =new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_06\\a.txt",true);
//2.写入数据
String str="huangmiqipiaozhisheng";
byte[] arr = str.getBytes();//把字符串数组变成字节数组
/*System.out.println(Arrays.toString(arr));//把arr数组变成字符串进行打印*/
fos.write(arr);
//再次写出一个换行符即可
String wrap="\r\n";
fos.write(wrap.getBytes());
//写入第二个数据
String str1="huang";
fos.write(str1.getBytes());
fos.close();
}
}
字节输入流:
public class demo03 {
public static void main(String[] args) throws IOException {
/*字节输入流FileInputStream需求:
读取文件中的数据
实现步骤:
1.创建对象
2.读取数据
3.释放资源
*/
//1.创建对象
FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_06\\a.txt");
//2.读取数据
int b1=fis.read();//只调用一次,所以只读取到的是第一个字符
System.out.println(b1);
//字节输入流循环读入数据
int b;
while((b=fis.read())!=-1){
System.out.print((char)b);
}//需要注意运算符的优先次序,赋值语句的优先次序最低,所以需要添加小括号来限制
//释放资源
fis.close();
}
}
字符集:
(GBK):完全兼容ASCII字符集
一个英文占一个字节,二进制的第一位是0;
一个中文占两个字节,二进制高位字节第一位是1;
(UNICODE):采用UTF-8编码方式,英文占一个字节,二进制第一位是0,转成十进制是正数
中文占三个字节,二进制第一位是1,转成十进制是负数
出现乱码的原因:
1.用字节流读取文件(字节流只能读取一个字节)
2.编码和解码的方式不统一(编码解码时使用同一个码表,同一个编码方式)
字符输入流:
public class demo01 {
public static void main(String[] args) throws IOException {
/* //创建对象
public FileReader(File file) 创建字符输入流关联本地文件
public FileReader(String pathname) 创建字符输入流关联本地文件
第二步:读取数据
public int read() 读取数据,读到末尾返回-1
public int read(char[] buffer) 读取多个数据,读到末尾返回-1
第三步:释放资源
public void close() 关流
*/
//1.创建文件对象
FileOutputStream fos =new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\a.txt");
//2.写入数据
String str="朴志晟";
byte[] arr = str.getBytes();//把字符串数组变成字节数组
/*System.out.println(Arrays.toString(arr));//把arr数组变成字符串进行打印*/
fos.write(arr);
//创建filereader 对象
FileReader fr=new FileReader("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\a.txt");
char[] ar=new char[2];
int ch;
//read(chars):读取数据,解码,强转三步合并
while((ch=fr.read(ar))!=-1){
//把数组中的数据变成字符串并进行打印,实际读了多少个数据就转成多少个
System.out.print(new String(ar,0,ch));
}
fr.close();
}
}
字符输出流:
public class demo02 {
public static void main(String[] args) throws IOException {
FileWriter fos=new FileWriter("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\b.txt",true);
//一次写一个字符
// fos.write(25105);
//一次写到文件中字符串的一部分
//fos.write("我爱小米",2,2);
//写出一个字符数组
char[] chrs={'a','b','c','d','e','f','g','h'};
fos.write(chrs);
fos.close();
}
}
运行结果如下:
因为把续写开关打开,所以之前写的数据不会被覆盖
加密和解密文件:
public class demo03 {
public static void main(String[] args) throws IOException {
//1.创建对象关联文件
FileInputStream fis=new FileInputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\jisung.03.jpg");
//2.创建对象关联文件
FileOutputStream fos =new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\ency.03.jpg");
//加密处理
int b;
while ((b=fis.read())!=-1){
fos.write(b^2);
}
//释放资源
fis.close();
fos.close();
}
}
运行结果如下:
字节缓冲流的拷贝问题:
public class demo04 {
public static void main(String[] args) throws IOException {
/* 需求:利用字节缓冲流拷贝文件
字节缓冲输入流的构造方法:public BufferedInputStream(InputStream is)
字节缓冲输出流的构造方法:public BufferedOutputStreram(OutputStreram os)
*/
//1.创建缓冲流对象
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\a.txt"));
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\copy.txt"));
//2.拷贝(一次读写多个字节)
byte[] buf=new byte[1024];
int len;
while((len=bis.read(buf))!=-1){
bos.write(buf,0,len);
}
//释放资源
bis.close();
bos.close();
}
}
运行结果:
字符缓冲流:
特点:拥有两个特有的方法---BufferedReader:readline() //字符缓冲输入流
BufferedWriter:newline() //字符缓冲输出流
public class demo05 {
public static void main(String[] args) throws IOException {
/*字符缓冲流:
构造方法:
public BufferedWriter(Wrtiter r)
特有方法:
public void newline() //跨平台的换行
*/
//1.创建字符缓冲流的对象
BufferedWriter bw=new BufferedWriter(new FileWriter("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\c.txt"));
//2.写出数据
bw.write("你最美");
bw.newLine();
bw.write("你最好看");
bw.newLine();
//3.释放资源
bw.close();
}
}
运行结果:
转换流基本用法:
1.读取文件数据
第一种:已经被淘汰的方法
//创建对象并指定字符编码
InputStreamReader is= new InputStreamReader(new FileInputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\demo.txt"),"GBK");
//2.读取数据
int ch;
while((ch=is.read())!=-1){
System.out.print((char)ch);
}
//3.释放资源
is.close();
第二种:更加简洁方便
FileReader fr = new FileReader("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\demo.txt", Charset.forName("GBK"));
//2.读取数据
int ch;
while((ch=fr.read())!=-1){
System.out.print((char)ch);
}
fr.close();
2.写入数据
//创建转换流对象
FileWriter fw = new FileWriter("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_07\\de.txt", Charset.forName("gbk"));
//读入数据
fw.write("你好漂亮");
//释放资源
fw.close();