存储数据的方案File和文件数据的操作IO流,学习字节流和字符流,了解框架和IO框架Commons IO
目录
1.File
(1)创建对象
(2)常用方法
【1】判断类型,获取信息
【2】创建文件,删除文件
编辑
【3】遍历文件夹
2.方法递归
(1)递归形式
(2)应用
(3)算法思想
(4)*文件搜索
3.字符集
(1)字符集介绍
(2)编码,解码操作
4.IO流
(1)IO流概述
【1】IO流介绍
【2】应用场景
【3】分类
(2)字节流
【1】文件字节输入流
【2】文字字节输出流
【3】案例
(3)释放资源的方式
【1】try-catch-finally
【2】try-with-resource
(4)字符流
【1】文件字符输入流
【2】文件字符输出流
(5)缓冲流
【1】字节缓冲流
【2】字符缓冲流
【3】性能分析
(6)转换流
【1】字符输入转换流
【2】字符输出转换流
(7)打印流
(8)数据流
(9)序列化流
(10)内容补充:IO框架
1.File
是java.io包下的类,File类的对象,代表当前操作系统的文件。只能对文件本身进行操作,不能读写文件里存储的数据
(1)创建对象
构造器 | 说明 |
public File (String pathname) | 根据文件路径创建文件对象 |
public File(String parent,String child) | 根据父路径和子路径名字创建文件对象 |
public File(FIle parent,String child) | 根据父路径对应文件对象和子路径名字创建文件对象 |
package File_IO.file;
import java.io.File;
public class Text {
public static void main(String[] args) {
//1.创建文件对象
// 路径分割符 \\
File f1 = new File("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\data.txt");
System.out.println(f1.length()); //文件大小 字节个数
//File对象是可以之地啊一个不存在的文件路径
File f2= new File("D:/resource");
System.out.println(f2.length());
System.out.println(f2.exists()); //判断是否为空文件 //false
//需要定位的文件在模块里 如何定位
//绝对路径 //带盘符
// File f4 = new File("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\File_IO\\file\\data.txt");
//相对路径(重点)不带盘符 默认到工程下去找文件
File f4 = new File("JAVA_study\\Collection\\src\\File_IO\\file\\data.txt");
System.out.println(f4.length());
}
}
(2)常用方法
【1】判断类型,获取信息
方法名 | 说明 |
public boolean exists() | 判断当前文件对象,对应的的文件路径是否存在,存在返回ture |
public boolean isFile() | 判断当前文件对象指代的是否是文件,是则返回ture |
public boolean isDirectory() | 判断当前文件对象指代的是否是文件夹,是则返回true |
public String getName() | 获取文件的名称(包含后缀) |
public long length() | 获取文件的大小,返回字节个数 |
public long lastModified() | 获取文件的最后修改时间 |
public String getPath() | 获取创建文件对象时,使用的路径 |
public String getAbsolutePath() | 获取绝对路径 |
package File_IO.file;
import java.io.File;
import java.text.SimpleDateFormat;
public class Text1 {
public static void main(String[] args) {
File f1 = new File("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\data.txt");
//public boolean exists() 判断当前文件对象,对应的的文件路径是否存在,存在返回ture
System.out.println(f1.exists());
//public boolean isFile() 判断当前文件对象指代的是否是文件,是则返回ture
System.out.println(f1.isFile());
//public boolean isDirectory() 判断当前文件对象指代的是否是文件夹,是则返回true
System.out.println(f1.isDirectory());
//public String getName() 获取文件的名称(包含后缀)
System.out.println(f1.getName());
//public long length() 获取文件的大小,返回字节个数
System.out.println(f1.length());
//public long lastModified() 获取文件的最后修改时间
long time = f1.lastModified();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH :mm:ss");
System.out.println(sdf.format(time));
//public String getPath() 获取创建文件对象时,使用的路径
System.out.println(f1.getPath());
//public String getAbsolutePath() 获取绝对路径 //相对路径可以转换到绝对路径
System.out.println(f1.getAbsoluteFile());
}
}
【2】创建文件,删除文件
方法名 | 说明 |
public boolean creatNewFile() | 创建一个新文件,内容为空 创建成功返回true |
Public boolean mkdir() | 用于创建文件夹 注意只能创建一级文件夹 |
public boolean mkdirs() | 用于创建文件夹 注意 可以创建多级文件夹 |
public boolean delete() | 删除文件,空文件 注意 不能删除非空文件 |
package File_IO.file;
import java.io.File;
import java.io.IOException;
public class Text2 {
public static void main(String[] args) throws IOException {
//1.public boolean creatNewFile() 创建一个新文件,内容为空 创建成功返回true
//如果文件已经创建 那么此时再进行创建会返回失败
File f1 = new File("C:/Users/22935/IdeaProjects/JAVA_study/data2.txt");
System.out.println(f1.createNewFile());
//2.Public boolean mkdir() 用于创建文件夹 注意只能创建一级文件夹
File f2 = new File("D:/resource");
System.out.println(f2.mkdir());
//3.public boolean mkdirs() 用于创建文件夹 注意 可以创建多级文件夹
File f3 = new File("D:/resource/aaa/bb/cc");
System.out.println(f3.mkdirs());
//4.public boolean delete() 删除文件,空文件 注意 不能删除非空文件
//空文件夹也可以删除
System.out.println(f1.delete());
}
}
【3】遍历文件夹
方法名 | 说明 |
Public string[ ] list() | 获取当前目录下所有的一级文件名称到一个字符串数组 |
public File[ ] listFiles() | 获取当前目录下所有等待一级文件对象到一个对象数组中 |
package File_IO.file;
import java.io.File;
public class Text3 {
public static void main(String[] args) {
//1.public String [] list() 获取当前目录下所有的一级文件名称到一个字符串数组
File f1 = new File("D:/23130405班");
String [] name = f1.list();
for (String s : name) {
System.out.println(s);
}
//2.public File [] listFile() (重点) 获取当前目录下所有等待一级文件对象到一个对象数组中
File [] files = f1.listFiles();
for (File file : files) {
System.out.println(file.getAbsolutePath());
}
}
}
使用listfiles方法的注意事项
- 当主调是文件或路径不存在时,返回null。
- 当主调是空文件时,返回一个长度为零的数组。
- 当主调是一个有内容的文件夹时,将里面一所有的一级文件和文件夹的路径都放在file数组中返回
- 当主调是一个文件夹里面有隐藏文件时,将里面所有的文件和文件路径都放在file数组中,包括隐藏文件
- 当主调是一个文件夹,但没有权限访问该文件夹时返回null。
2.方法递归
方法递归是一种算法,广泛使用,形式上来看是方法调用自身的形式
(1)递归形式
- 直接递归:方法自己调用自己
- 间接递归:调用其他方法,其他方法又调回自己
(2)应用
需求:计算n的阶乘
package File_IO.file;
public class Text4 {
public static void main(String[] args) {
System.out.println(fun(5));
}
public static int fun(int n){
if(n == 1){return 1;}
else {return fun(n-1)*n;}
}
}
(3)算法思想
算法三要素
- 递归公式
- 递归的终结点
- 递归的方向必须走向终结点
(4)*文件搜索
需求:从D盘中,搜索找到“QQ.exe”这个文件,找到后输出其位置
package File_IO.file;
import java.io.File;
public class Text5 {
public static void main(String[] args) {
search(new File("D:/"),"QQ.exe");
}
public static void search(File file,String filename){
//1.拦截非法情况
if(file == null || !file.exists() || file.isFile()){
return;
}
File [] files = file.listFiles();
if(files != null && files.length != 0){
for (File f : files) {
if(f.isFile()){
if(f.getName().equals(filename)) {
System.out.println("已找到文件位置");
System.out.println(f.getAbsolutePath());
}
}
else{
search(f,filename);
}
}
}
}
}
需求:删除非空文件夹
package File_IO.file;
import java.io.File;
public class Text6 {
public static void main(String[] args) {
//目标 删除非空文件夹,独立功能独立成方法
File file = new File("D:/");
deleteDir(file);
}
public static void deleteDir(File dir){
if(dir == null ||!dir.exists()){
return;
}
if(dir.isFile()){
dir.delete();
return;
}
File[] files = dir.listFiles();
if(files == null){
return;
}
if(files.length == 0){
dir.delete();
return;
}
for (File file : files) {
if(file.isFile()){
file.delete();
}
else{
deleteDir(file);
}
}
dir.delete();
}
}
3.字符集
(1)字符集介绍
标准Ascll字符集
美国信息交换标准化码 英文,符号 共128个字符 首尾是0
GBK(汉字内码)
包含两万多个汉字字符(一个中文字符编码成两个字节的形式)兼容Ascll字符集
Uniccode字符集
(统一码,万国码)国际组织制定2,可以容纳世界上所有文字,所有字符集
UTF-32 4个字节表示一个字符 空间占用比较大 通讯效率低
UTF-8 采用可变编码方案 分四个长度区 1,2,3,4
- 英文字符,数字等占1个字节
- 汉字占用3个字节
UTF-8 编码方式 |
0XXXXXXX(ASCLL码) |
110XXXXX 10XXXXXX |
1110XXXX 10XXXXXX 10XXXXXX |
11110XXX 10XXXXXX 10XXXXXX 10XXXXXX |
(2)编码,解码操作
- 字符编码时使用的字符集,和解码时使用的字符集必须一致否则会出现乱码
- 英文,数字一般不会乱码,很多都兼容了ASCLL编码
编码:
string 提供方法 | 说明 |
byte [] getBytes() | 使用平台的默认字符集将该string编码为1系列字体,将结果存储到新的字节数组中 |
byte [] getBytes(String charsetName) | 使用指定字符集将该string编码为一系列字节结果存储到新的字节数组中。 |
解码:
string 提供方法 | 说明 |
String (byte [] bytes) | 通过使用平台的默认字符集解码指定字节数组来构建新的string |
String (byte [] bytes, String charsetName) | 通过指定字符集解码指定的字节数组来构建string |
package File_IO.file;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class Text7 {
public static void main(String[] args) throws UnsupportedEncodingException {
//1.编码
String data = "w愿爱你1314";
byte [] bytes = data.getBytes(); //默认按照平台 UTF-8
System.out.println(Arrays.toString(bytes));
System.out.println(bytes.length);
//指定字符集编码
byte [] bytes1 = data.getBytes("GBK"); //抛出一个异常
System.out.println(Arrays.toString(bytes1));
//2.解码
String s1 = new String(bytes);
System.out.println(s1);
//String s2 = new String(bytes1);//会出现乱码 编码方式不一致
String s2 = new String(bytes1,"GBK");
System.out.println(s2);
}
}
4.IO流
(1)IO流概述
【1】IO流介绍
I 指input 称为输入流 负责把数据读到内存/网络中去
O 指output 称为输出流 负责写出数据
【2】应用场景
数据传输,数据存储...
【3】分类
(2)字节流
【1】文件字节输入流
FileInputStream
作用:以内存为基准,可以将磁盘文件中的数据以字节的形式读入到内存中
构造器 说明 Public FileInputStream(File file) 创建字节输入流管道与源文件接通 public FileInputStream(String pathname) 创建字节输入流管道与源文件接通
方法名称 说明 public int read() 每次读取一个字节返回,如果发现没有数据可读会返回-1 public int read(byte[ ] buffer) 每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读返回-1
package IO_Study;
import java.io.*;
public class Text {
public static void main(String[] args) throws IOException {
//1.创建文字字节输入流 与源文件接通
// InputStream is = new FileInputStream(new File("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data01.txt"));
InputStream is = new FileInputStream("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data01.txt");//可以直接填入地址 推荐使用
//2.开始读取文件字节数据
int b1 = is.read();
System.out.println((char) b1);
int b2 = is.read();
System.out.println((char) b2);
int b3 = is.read();
System.out.println((char) b3); // 没有数据就返回-1
//循环改造上述代码
int b;
while((b = is.read() )!= -1){
System.out.println((char) b);
} //读取性能很差
//读取汉字会出现乱码
}
}
package IO_Study;
import java.io.*;
public class Text {
public static void main(String[] args) throws IOException {
//1.创建文字字节输入流 与源文件接通
// InputStream is = new FileInputStream(new File("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data01.txt"));
InputStream is = new FileInputStream("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data01.txt");//可以直接填入地址 推荐使用
//2.读取文件的字节内容,每次多次读取
//读取完毕返回-1
/*byte [] buffer = new byte[3];
int len = is.read(buffer);
String rs = new String(buffer);
System.out.println(rs);
System.out.println("当前读取字符的数量" + len);
*/
//再次王往一个数组中读取数据时 并不会重置数组
//注意:读取多少 倒出多少
//3.循环改造
byte [] buffer1 = new byte[3];
int len;
while((len = is.read(buffer1)) != -1){
String rs1 = new String(buffer1,0,len);
System.out.println(rs1);
}
is.close(); //关闭流
}
}
package IO_Study;
import javax.imageio.stream.FileImageInputStream;
import java.io.*;
public class Text1 {
public static void main(String[] args) throws IOException {
//一次读取完文件全部字节到一个数组中
//1.创建一个字节输入流
InputStream is = new FileInputStream("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data01.txt");
//方式一 :.准备一个字节数组,大小与文件的大小正好一样大 方案对于内存有要求 文件过大会导致内存溢出
//读写文本更适合使用字符流
File f = new File("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data01.txt");
long size = f.length();
byte[] buffer = new byte[(int) size];
int len = is.read(buffer);
System.out.println(new String(buffer));
System.out.println(size);
System.out.println(len);
//方式二 :使用java提供的方法 readAllBytes
byte[] buffer1 = is.readAllBytes();
System.out.println(buffer1);
}
}
【2】文字字节输出流
FileOutputStream
作用:
构造器 说明 public FileOutputStream(File file) 创建字节输出流管道与源文件对象接通 public FileOutputStream(String filepath) 创建字节输出流管道与源文件对象接通 public FileOutputStream(File file,boolean append) 创建字节输出流管道与源文件对象接通,可以追加数据 public FileOutputStream(String filepath,boolean append) 创建字节输出流管道与源文件对象接通,可以追加数据
方法名称 说明 public void write(int a) 写一个字节出去 public void write(byte[] buffer) 写一个字节数组出去 public void write(byte[] buffer,int pos,int len) 写一个字节数组的一部分出去 public void close() throws IOException 关闭流
package IO_Study;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Text2 {
public static void main(String[] args) throws Exception {
//创建字节输出流
OutputStream os = new FileOutputStream("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data01.txt",true);//可以追加数据的管道
//写入文字字节
os.write(97); //一个字节数据
os.write('w');//也是一个字节
byte [] bytes = "万水千山 我陪你去看".getBytes();
os.write(bytes);
//换行符号
os.write("\r\n".getBytes());
os.write(bytes,0,12); //写字节的一部分
os.close();
}
}
【3】案例
文件复制
从文件位置创建字节输入到内存中,然后再创建字节输出流管道输出文件到复制位置
package IO_Study;
import java.io.*;
public class Demo1 {
public static void main(String[] args) throws IOException {
//复制文件 - 图片
//1.创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("");
//2.创建一个字节输出流管道与源文件接通
OutputStream os = new FileOutputStream(""); //输出位置需要自己填入文件名
//3.创建一个字节数组,负责转移字节数据
byte[] buffer = new byte[1024]; //1KB
//4.从字节中输入流读取字节数据,写出到字节输出流,读多少写多少
int len; //记住每次读取多少个字节
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
os.close();
is.close();
System.out.println("复制完成");
}
}
字节流适合做一切文件的复制操作,转移完全部字节,只要复制后的文件格式一致就没有问题
(3)释放资源的方式
【1】try-catch-finally
finally 代码区的特点:无论try的程序是否正常执行,还是出现异常,最后都一定会执行finally区,除非JVM终止(不要在finally里写返回语句)
作用:一般用于在程序执行完成后进行资源的释放
package IO_Study;
import java.io.*;
public class Demo1 {
public static void main(String[] args) throws IOException {
//复制文件 - 图片
//1.创建一个字节输入流管道与源文件接通
InputStream is = null;OutputStream os = null;
try {
is = new FileInputStream("");
//2.创建一个字节输出流管道与源文件接通
os = new FileOutputStream(""); //输出位置需要自己填入文件名
//3.创建一个字节数组,负责转移字节数据
byte[] buffer = new byte[1024]; //1KB
//4.从字节中输入流读取字节数据,写出到字节输出流,读多少写多少
int len; //记住每次读取多少个字节
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
if(os != null) os.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
if(is != null) is.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
System.out.println("复制完成");
}
}
【2】try-with-resource
finally 语句臃肿 不雅观 JDK17后使用更加简单的资源释放方案try-with-resource
package IO_Study;
import java.io.*;
public class Demo1 {
public static void main(String[] args) throws IOException {
//复制文件 - 图片
try (
//1.创建一个字节输入流管道与源文件接通
InputStream is = new FileInputStream("");
//2.创建一个字节输出流管道与源文件接通
OutputStream os =new FileOutputStream(""); //输出位置需要自己填入文件名
//注意:这里只能放置资源对象(流对象)
//资源 资源都是会实现AutoCloseable接口
){
//3.创建一个字节数组,负责转移字节数据
byte[] buffer = new byte[1024]; //1KB
//4.从字节中输入流读取字节数据,写出到字节输出流,读多少写多少
int len; //记住每次读取多少个字节
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("复制完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
(4)字符流
【1】文件字符输入流
FileReader
作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中
构造器 说明 public FileReader(File file) 创建字符输入流管道与源文件接通 public FileReader(String pathname) 创建字符输入流管道与源文件接通
方法名称 说明 public int read() 每次读取一个字符返回,如果发现没有数据可读返回-1 public int read(char[ ] buffer) 每次用一个字符数组去读取数据,返回字符数组读取了多少字符,没有数据可读返回-1
package IO_Study;
import java.io.*;
public class Text3 {
public static void main(String[] args){
//1.创建一个文件字符输入流与源文件接通
try (Reader r = new FileReader("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data02.txt");){
//2.读取内容
//(1)每次读取一个字符 性能比较差
/* int c; //记录编号
while ((c = r.read()) != -1){
System.out.print((char) c); //英文和汉字都看做一个字符
}*/
//(2)每次读取多个字符
char[] buffer = new char[3];
int len; //记住每次读取了多少个字符
while((len = r.read(buffer)) !=-1){
System.out.print(new String(buffer, 0, len));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
【2】文件字符输出流
FileWrite
作用:以内存为基准,把内存中的数据以字符的形式写到文件中去
构造器 说明 public FileWriter(File fiel) 创建字符输出流管道与源文件对象接通 public FileWriter(String filepath) 创建字符输出流管道与源文件路径接通 public FileWriter(File file,booleanappend) 创建字符输出流管道与源文件对象接通,可追加数据 public FileWriter(String filepath,boolean append) 创建字符输出流管道与源文件路径接通,可追加数据
方法名称 说明 void write(int c) 写一个字符 void write(String str) 写一个字符串 void write(String str,int off,int len) 写一个字符串的一部分 void write(char[] cbuf) 写一个字符数组 void write(char[] cbuf,int off,int len) 写入字符数组的一部分
package IO_Study;
import java.io.FileWriter;
import java.io.Writer;
public class Text4 {
public static void main(String[] args) {
try(Writer fw = new FileWriter("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data02.txt",true)){
//1.void write(int c) 写一个字符
fw.write('a');
fw.write('b');
fw.write('c');
//void write(String str) 写一个字符串
fw.write("此生 只为你我相望");
//void write(String str,int off,int len) 写一个字符串的一部分
fw.write("愿意",0,1);
//void write(char[] cbuf) 写一个字符数组
char[] data = {'a','b','c'};
fw.write(data);
//void write(char[] cbuf,int off,int len) 写入字符数组的一部分
fw.write(data,0,2);
//字符输出流写出数据后,必须刷新流,或者关闭流,写出的数据才能生效
fw.flush(); //刷新流
//关闭流包含刷新操作
//适合做文本文件的操作(读写)
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
(5)缓冲流
对于原始流进行包装,以提高原始数据读写数据的性能
【1】字节缓冲流
提高字节流读写数据的性能
原理:字节缓冲输入流自带8KB缓冲池,缓冲输出流也自带8KB缓冲池
构造器 说明 pubilc BufferedInputStream(InputStream is) 把低级的字节输入流包装成一个高级的缓冲字节输入流,从而提高读数据的性能 public BufferedOutputStream(OutputStream os) 把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高读数据的性能
package IO_Study;
import java.io.*;
public class Text5 {
public static void main(String[] args) {
try (
//1.定义一个字节输入包装流包装原始的输入流
InputStream is = new FileInputStream("");
InputStream bis = new BufferedInputStream(is);
OutputStream os = new FileOutputStream(""); //输出位置需要自己填入文件名
OutputStream bos = new BufferedOutputStream(os);
){
byte[] buffer = new byte[1024]; //1KB
int len;
while((len = bis.read(buffer)) != -1){
bos.write(buffer,0,len);
}
System.out.println("复制完成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
【2】字符缓冲流
BufferedReader(字符缓冲输入流)
作用:提高字符流输入字符数据的性能
原理:字符缓冲输入流自带8KB缓冲池
构造器 说明 public BufferedReader(Reader r) 把低级的字符输入流包装成字符缓冲输入流管道,从而提升性能
方法 说明 public String readLine() 读取一行数据返回,没有数据可读了,就返回null
package IO_Study;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.Reader;
public class Text6 {
public static void main(String[] args) {
try (
Reader fr = new FileReader("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data02.txt");
BufferedReader bfr = new BufferedReader(fr);
){
char[] buffer = new char[3];
int len;
while((len = bfr.read(buffer)) != -1){
System.out.println(new String(buffer, 0, len));
}
//特色功能 按行读取
String line;
while((line = bfr.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
BufferedWriter(字符缓冲输出流)
作用:提高字符流输出字符数据的性能
原理:字符缓冲输出流自带8KB缓冲池
构造器 说明 public BufferedWriter(Writer r) 把低级的字符输出流包装成字符缓冲输出流管道,从而提升性能
方法 说明 public void newLine() 换行
package IO_Study;
import java.io.*;
public class Text7 {
public static void main(String[] args) {
try(
Writer fw = new FileWriter("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data03.txt");
BufferedWriter bfw = new BufferedWriter(fw);
){
bfw.write('a');
bfw.write('b');
bfw.write('v');
bfw.write("\r\n");
bfw.write("爱你");
bfw.newLine();
bfw.write("爱你");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
【3】性能分析
测试案例:使用两种流分别按照一个字节一个字节的形式和按照字节数组的形式复制文件
计算耗费时间来比较性能
(6)转换流
如果代码编码和被读取的文本文件的编码是一致的,使用字符流读取文本文档时不会出现乱码,不一致时就会出现乱码
package IO_Study;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
public class Text8 {
public static void main(String[] args) {
//1.文件字符输入流
try(
Reader r = new FileReader("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data03.txt");
//Reader r = new FileReader("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data04.txt");
BufferedReader br = new BufferedReader(r);
) {
String line;
while((line = br.readLine()) != null){
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
【1】字符输入转换流
InputStreamReader
- 解决不同编码,字符流读取文本内容乱码的问题
- 解决思路:获取文件的原始的字节流,再按照真实的字符集编码转成字符输入流
构造器
说明
public InputStreamReader(InputStream is)
把原始的的字节输入流,按照代码默认的编码转换成字符输入流
public InputStreamReader(InputStream is,String charset)
把原始的字节输入流,按照指定的字符集编码转换成字符输入流
package IO_Study;
import java.io.*;
public class Text9 {
public static void main(String[] args) {
try ( InputStream is = new FileInputStream("C:\\Users\\22935\\IdeaProjects\\JAVA_study\\Collection\\src\\IO_Study\\data04.txt");
Reader isr = new InputStreamReader(is,"GBK");
BufferedReader br = new BufferedReader(isr);
){
} catch (Exception e) {
e.printStackTrace();
}
}
}
【2】字符输出转换流
控制写出去的字符使用什么字符集编码
- 调用String提供的getBytes方法解决
- 使用“字符输出转换流”
构造器 说明 Public OutputStreamWriter(OutputStream os) 可以把原始的字节输出流,按照代码默认编码转换为字符输出流 public OutputStreamWriter(OutputStream os,String charset) 把原始的字节输出流,按照指定的编码转换为字符输出流
(7)打印流
【1】PrintStream(字节)【2】PrintWriter(字符)
作用:打印流可以实现更方便,更高效的打印数据出去
构造器 说明 public PrintStream(OutputStream/File/String) 打印流直接通向字节输出流文件文件路径 public PrintStream(String filename,Charset charset) 可以指定写出去的字符编码 public PrintStream(OutputStream out,boolean autoFlush) 可以指定实现自动刷新 public PrintStream(OutputStream out,autoFlush,String encoding) 可以指定实现自动刷新,并可指定字符的编码
方法 说明 public void println(Xxx xx) 打印任意类型的数据出去 public void write(int/byte[] /byte[]的一部分) 可以支持写字节数据出去
package IO_Study;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
public class Text10 {
public static void main(String[] args) {
try ( //1.创建一个打印流
PrintStream ps = new PrintStream("");
){
ps.println(97); //打印97
ps.println('a');
ps.println("前面都白雪");
byte [] bytes = new byte[3];
bytes[0] = 97;
ps.write(97); //a
ps.write(bytes);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
输出语句的重定向
修改System中的out的文件位置
package IO_Study; import java.io.FileNotFoundException; import java.io.PrintStream; public class Text11 { public static void main(String[] args) { System.out.println("1"); System.out.println("2"); try(PrintStream ps = new PrintStream("");) //定向输出到文件中 { System.setOut(ps); System.out.println("2"); } catch (FileNotFoundException e) { throw new RuntimeException(e); } System.out.println("3"); System.out.println("4"); } }
(8)数据流
DataOutputstream(数据输出流)
作用:允许把数据和其类型一并写出去
构造器 说明 public DataOutputstream(Out putStream out) 创建新数据输出包装基础的字节输出流
方法 说明 public final void writeByte(int v) throw IOException 将byte类型的数据写入基础字节输出流 public final void writeInt(int v) throw IOException 将int类型的数据写入基础字节输出流 public final void writeDouble(int v) throw IOException 将Double类型的数据写入基础字节输出流 public final void writeUTF(String str) throw IOException 将字符串类型的数据按照UTF-8编码成字节写入基础字节输出流 public final void write(int /byte[]) throw IOException 支持写字节数据出去
package IO_Study;
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class Text12 {
public static void main(String[] args) {
try(
DataOutputStream dos = new DataOutputStream(new FileOutputStream(""));
) {
dos.writeInt(12);
dos.writeDouble(12.0);
dos.writeBoolean(true);
dos.writeUTF("韩");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
DataInputStream(数据输入流)
作用:读取数据输出流输出的数据
构造器 说明 pubic DataInputStream(InputStream is) 创建新数据输入流包装基础的字节输入流
方法 说明 public fianl byte readByte() throws IOException 读取字节数据返回 public fianl int readInr() throws IOException 读取int类型的数据返回 public fianl double readDouble() throws IOException 读取double类型的数据返回 public fianl String readUTF() throws IOException 读取字符串数剧返回 public int readByte() /read(byte[]) 支持读写字节数据进来
(9)序列化流
ObjectInputStream(对象字节输出流)
把java对象序列化,把java对象存入到文件中去
package IO_Study;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Text13 {
public static void main(String[] args) {
//2.创建一个对象字节输出流包装
try( ObjectOutputStream os =new ObjectOutputStream(new FileOutputStream(""))){//文件位置
//1.创建一个对象
Student stu = new Student("韩",19,"050501");
//3.序列化文件
os.writeObject(stu);
System.out.println("ok");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
package IO_Study;
import java.io.Serializable;
//注意 要实现序列化 要实现接口
public class Student implements Serializable {
private String name;
private int age;
private String passWord;
public String getName() {
return name;
}
public Student() {
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public Student(String name, int age, String passWord) {
this.name = name;
this.age = age;
this.passWord = passWord;
}
}
ObjectOutputStream(对象字节输入流)
把java对象反序列化,把存储在文件中的java对象读入到内存中
package IO_Study;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class Text14 {
public static void main(String[] args) {
try(
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(""));
){
Student student = (Student) ois.readObject();
System.out.println(student);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
一次序列化多个对象,使用集合存储多个对象即可,ArrayList已经实现了序列化接口
(10)内容补充:IO框架
框架:解决某类的问题,编写的一套类,接口等,是一个半成品
好处:会得到优秀的架构,并提高开发效率
IO框架
封装了JAVA提供的对文件数据进行操作的代码,对外提供了更简单的方式对文件进行操作,对数据进行读写的。
学习时间:2024-8-21