JavaIO
IO操作的本质就是字节流。
一般情况下,字节流处理二进制文件。字符流处理文本文件。
创建文件
方式1:new FIle(String pathname)
要加文件格式
@Test
public void create1() {
String filePath = "F:\\new1.txt";// "\\"前面是新建的位置,后面是文件名和格式
File file = new File(filePath);//此时new在java内存中
//不运行try,catch时,只是一个java对象,无法创建到磁盘中
try {
file.createNewFile();//执行此句的new后才写入硬盘
System.out.println("文件创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
方式2:new FIle(File parent,String child)
@Test
public void create2(){
File parentfile = new File("F:\\d\\");
String filename = "new2.txt";
File file = new File(parentfile, filename);
try {
file.createNewFile();
System.out.println("成功");
} catch (IOException e) {
e.printStackTrace();
}
}
方式3:new FIle(File parent,String child) 根据父母类+子路径构建
@Test
public void create3(){
String parentPath = "F:\\d\\";
String filename = "new3.txt";
File file = new File(parentPath,filename);
try {
file.createNewFile();
System.out.println("成功");
} catch (IOException e) {
e.printStackTrace();
}
}
获取文件基本信息
@Test
public void info(){
//先创建文件对象
File file = new File("F:\\new1.txt");
//调用相应的方法,得到对应的结果
System.out.println("文件名字:"+file.getName());
System.out.println("文件绝对路径:"+file.getAbsolutePath());
System.out.println("文件父目录:"+file.getParentFile());
System.out.println("文件大小(字节):"+file.length());
System.out.println("文件是否存在:"+file.exists());//T
System.out.println("是不是一个文件:"+file.isFile());//T
System.out.println("是不是一个目录:"+file.isDirectory());//F
}
目录操作
File file = new File("F:\\new1.txt");
file.delete(); //删除文件
file.exists(); //查看文件是否存在
file.mkdir(); //创建文件,一级目录
file.mkdirs(); //创建文件,多级目录
删除
//判断F:\\new1.txt 是否存在,如果存在就删除
@Test
public void m1(){
File file = new File("F:\\new1.txt");
if (file.exists()){
if (file.delete()){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
}else {
System.out.println("不存在");
}
}
创建
//判断D:\\Demo1 是否存在,如果存在就提示已存在,否则创建
//mkdirs多级目录 mkdir一级目录
@Test
public void m3(){
File file = new File("F:\\Demo1\\a\\s");
if (file.exists()){
System.out.println("已存在");
}else {
if (file.mkdirs()) {
System.out.println("创建成功");
}else{
System.out.println("创建失败");
}
}
}
java的IO流
UTF-8,一个汉字占三个字节
包含四个抽象类
- Inputstream(字节流)
- Outputstream(字节流)
- Reader(字符流)
- Writer(字符流)
字节流可以用来处理图片,音频等格式并且做到无损传输
FileInputstream
单字节读取
@Test
public void readFile1(){
String filePath = "F:\\hellow.txt";
int readDate = 0;
FileInputStream fileInputStream = null;
try {
//创建FileInputStream对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
//从该输入流读取一个字节的数据。如果没有输入可用,此方法将组织。
//如果返回-1,表示读取完毕。
while ((readDate = fileInputStream.read()) != -1){
System.out.print((char) readDate);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
read(byte[] b)读取文件,提高效率(8个字节读取)
@Test
public void readFile2(){
String filePath = "F:\\hellow.txt";
int readDate = 0;
//字节数组
byte[] buf = new byte[8];//一次读取8个字节
int readLen = 0;
FileInputStream fileInputStream = null;
try {
//创建FileInputStream对象,用于读取文件
fileInputStream = new FileInputStream(filePath);
//从该输入流读最多b.length个字节的数据到字节数组。
//如果返回-1,表示读取完毕。
//如果读取正常,返回实际读取的字节数
while ((readLen = fileInputStream.read(buf)) != -1){
System.out.print(new String(buf,0, readLen));//显示数组
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件中带汉字的话可能会有错误,如按8字节读取“hellow,word!好的我举得”则会被读成“hellow,word!好���我举得”。
FileOutputstream
写文件
FileOutputStream,将数据写到文件中
如果文件不存在,则创建该文件
@Test
public void writeFile(){
/**
* 1、new FileOutputStream(filePath) 创建方式,当写入内容时,会覆盖原来的内容
* 2、new FileOutputStream(filePath,true) 创建方式是追加到文件的后面
*
*/
//创建fileOutputStream 对象
String filePath = "F:\\a.txt";
FileOutputStream fileOutputStream = null;
try {
//得到fileOutputStream对象
fileOutputStream = new FileOutputStream(filePath);
//写入一个字节
fileOutputStream.write('a');//
//写入字符串
String str = "hellow";
//str.getBytes() 可以把 字符串-->字节数组
fileOutputStream.write(str.getBytes());
fileOutputStream.write(str.getBytes(),0,str.length());
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件的拷贝
public static void main(String[] args) {
//将D:\\a.txt 拷贝到 D:\\Demo1
/**
* 1、创建文件的输入流,将文件读入到程序
* 2、创建文件的输出流,将读取到的文件数据,写入到指定的文件
*/
String srcFilePath = "F:\\1.png";
String destFilePath = "F:\\d\\2.txt";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcFilePath);
fileOutputStream = new FileOutputStream(destFilePath);
//定义一个字节数组,提高效率
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = fileInputStream.read(buf)) != -1){
//读取到后,就写入到文件 通过fileOutputStream
//即,一边读一边写
fileOutputStream.write(buf,0,readLen);//一定要使用这个方法
}
System.out.println("拷贝OK");
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭输入流和输出流
try {
if (fileInputStream != null){
fileInputStream.close();}
if (fileOutputStream != null){
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileReader
单字节读取
@Test
public void readFile1(){
String filePath = "F:\\a.txt";
java.io.FileReader fileReader = null;
int data = ' ';
//1、创建FileReader对象
try {
fileReader = new java.io.FileReader(filePath);
//循环读取 使用read
while ((data = fileReader.read())!=-1){
// System.out.print(data);
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fileReader!=null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
多字节读取(使用字符数组读取)
@Test
public void readFile2(){
String filePath = "F:\\a.txt";
java.io.FileReader fileReader = null;
int readLen = 0;
char[] buf = new char[8];
//1、创建FileReader对象
try {
fileReader = new java.io.FileReader(filePath);
//循环读取 使用read(buf),返回的是实际读取到的字符数
//返回-1,说明文件结束
while ((readLen = fileReader.read(buf))!=-1){
// System.out.print(readLen);
System.out.print(new String(buf,0,readLen));//代表从第一个到读到的最后一个。
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fileReader!=null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileWriter
public static void main(String[] args) {
String filePath = "F:\\a.txt";
java.io.FileWriter fileWriter = null;
char[] chars = {'a','b','c'};
try {
fileWriter = new java.io.FileWriter(filePath);
//1、Writer(int) 写入单个字符。
fileWriter.write("HH");
//2、Writer(char []) 写入指定数组。
fileWriter.write(chars);
//3、Writer(char [],off,len) 写入指定数组的指定部分。
fileWriter.write("我觉得可以".toCharArray(),0,3);
//4、Writer(string) 写入整个字符串。
fileWriter.write(" 你好北京");
//5、Writer(string,off,len) 写入字符串的指定部分。
fileWriter.write(" 上海你好",0,3);
//数据量大的时候可进行循环操作
} catch (IOException e) {
e.printStackTrace();
}finally {
//对应FileWriter ,一定要关闭流,或flush才能真正的把数据写入文件
try {
fileWriter.flush();
//close 关闭文件流,等价于flush+关闭。
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
处理流(包装流)
对节点流进行包装,使它功能更强大。
通过对父类属性的创建,实现子类中的一些方法
Reader_test 父类
public abstract class Reader_test {
public abstract void read();
}
FileReader_test 子类
重写父类的方法
public class FileReader_test extends Reader_test {
public void read(){
System.out.println("对文件进行读取");
}
}
StringReader_test 子类
重写父类的方法
public class StringReader_test extends Reader_test {
public void read(){
System.out.println("读取字符串");
}
}
BufferReader_test 子类(实现对另外两个子类的包装)
创建属性是父类的对象
通过父类的对象调用其他两个子类
public class BufferReader_test extends Reader_test {
private Reader_test reader_test;//属性是Reader_test类型
public BufferReader_test(Reader_test reader_test) {
this.reader_test = reader_test;
}
//让方法更灵活,多次读取文件
public void read(int num){
for (int i = 0; i < num; i++) {
reader_test.read();
}
}
//拓展readString 批量处理字符串数据
public void read(){
}
}
test
new对象的时候需要创建其他两个子类的对象。
运行的时候先进入BufferReader_test 的read方法,随后进入其他两个子类的read方法。
public class test {
public static void main(String[] args) {
BufferReader_test bufferReader_test = new BufferReader_test(new FileReader_test());
// bufferReader_test.readFile(5);
bufferReader_test.read(5);
//希望通过BufferReader_test 多次读取字符串
BufferReader_test bufferReader_test1= new BufferReader_test(new StringReader_test());
bufferReader_test1.read(5);
}
}
bufferedReader
关闭bufferedReader流,实际上是关闭了底层流。
public class bufferedReader {
public static void main(String[] args) throws Exception {
String filePath = "F:\\hellow.txt";
//创建BufferedReader对象
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
//读取
String line;//按行读取
//bufferedReader.readLine() 按行读取,读取完返回空
while ((line = bufferedReader.readLine())!= null){
System.out.println(line);
}
//关闭流,只需要关闭bufferedReader就可以。底层会自动关闭节点流
bufferedReader.close();
}
}
bufferedWriter
没有查找到文件的时候会自动创建文件。
public class bufferedWriter {
public static void main(String[] args) throws IOException {
String filePath = "D:\\b.txt";
//创建对象
// 用于覆盖
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
/**
* 用于末尾添加
*BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath,true));
*/
bufferedWriter.write("hell ow1,你好!");
bufferedWriter.write("hell ow2,你好!"+'\n');//在末尾插入换行符。5=
bufferedWriter.newLine();//插入换行符
bufferedWriter.write("hell ow3,你好!");
bufferedWriter.close();
}
}
bufferCopy(字符流)
不能处理二进制文件
public static void main(String[] args) {
//BufferedReader BufferedWriter 按字符读取,不要操作二进制文件(ptf avi即图片,视频等)
String srcfilePath = "F:\\b.txt";
String destfilePath = "F:\\d\\a.txt";
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
String line;
try {
bufferedReader = new BufferedReader(new FileReader(srcfilePath));
bufferedWriter = new BufferedWriter(new FileWriter(destfilePath));
//读取写入
while ((line = bufferedReader.readLine())!=null){
//每读取一行就写入
bufferedWriter.write(line);
bufferedWriter.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (bufferedReader !=null) {
bufferedReader.close();
}
if (bufferedWriter!=null) {
bufferedWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
bufferCopy(字节流)
可以处理二进制文件(图片,音频等)
public static void main(String[] args) {
String srcFile = "D:\\new3.txt";
String destFile = "D:\\Demo1\\new3.txt";
byte[] buf = new byte[1024];
int readLin = 0;
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFile));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFile));
while ((readLin = bufferedInputStream.read(buf))!=-1){
bufferedOutputStream.write(buf,0,readLin);
}
System.out.println("拷贝完成");
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (bufferedInputStream!=null) {
bufferedInputStream.close();
}
if (bufferedOutputStream!=null) {
bufferedOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
序列化和反序列化
序列化:同时保存值和数据类型。
反序列化:将保存在文件的数据重新恢复成原来的对象(值和类型)。
如果想序列化保存,保存的类必须是可序列化的。为了使类可序列化可继承两个接口。 Serializable(无方法)或者Externalizable(包含方法需要实现)。推荐使用第一种。
序列化ObjectOutputStream
public static void main(String[] args) throws Exception{
//序列化后,保存的文件格式,不是存文本,而是按照它的格式来保存
String filePath = "F:\\new4.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到 F:\\new4.dat
oos.writeInt(100);//int--->integer(实现了Serializable)
oos.writeBoolean(true);//boolean--->Boolean(实现了Serializable)
oos.writeChar('a');//char-->Character(实现了Serializable)
oos.writeDouble(9.5);//double-->Double(实现了Serializable)
oos.writeUTF("可可");//String
//保存了一个dog对象
oos.writeObject(new Dog("aa",10,"日本","白色"));
oos.close();
System.out.println("保存完毕(可序列化)!");
}
Dog类
public class Dog implements Serializable {
//String,int的包装类都已经实现了Serializable接口
private String name;
private int age;
//序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员。
private static String nation;
private transient String color;
//serialVersionUID 序列化的版本号,可以提高兼容性。
//即,当增加新的Dog属性的时候不会认为是一个新的类,而会认为是Dog类的升级版。
private static final long serialVersionUID = 1L;
//序列化对象时,要求里面属性的类型也需要实现序列化接口。
private Master master = new Master();
public Dog(String name, int age ,String nation, String color) {
this.name = name;
this.age = age;
this.color=color;
this.nation = nation;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}'+nation + master;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
反序列化ObjectInputStream
public static void main(String[] args) throws IOException, ClassNotFoundException {
//指定反序列化的文件
String filePath = "F:\\new4.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
//读取
/**
* 1、读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致
*2、否则出现异常
*/
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
//dog的编译类型是Object,dog的运行类型是Dog
Object dog = ois.readObject();
System.out.println("运行类型="+dog.getClass());
System.out.println("dog信息=" + dog);
//特别重要的细节
//1、如果我们希望调用Dog的方法,需要向下转型。
//2、需要我们将Dog类的定义,放在到可以引用的位置。
Dog dog2 = (Dog)dog;
System.out.println(dog2.getName());
//关闭流 关闭外层流即可。底层自动关闭fileinputstream
ois.close();
}
标准输入流和标准输出流
System.in 标准输入 键盘
System.out 标准输出 显示器
public static void main(String[] args) {
//System 类的 public final static InputStream in = null;
//System.in 编译类型 InputStream
//System.in 运行类型 BufferedInputStream
//表示标准输入(键盘)
System.out.println(System.in.getClass());
//System 类的 public final static PrintStream out = null;
//System.out 编译类型 PrintStream
//System.out 运行类型 PrintStream
//表示标准输出(显示器)
System.out.println(System.out.getClass());
System.out.println("aaaa");
Scanner scanner = new Scanner(System.in);
System.out.println("输入内容:");
String next = scanner.next();
System.out.println(next);
}
转换流
InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)。
OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)。
InputStreamReader
public static void main(String[] args) throws IOException {
String filePath = "F:\\a.txt";
InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath),"utf-8");
//解读
//1、把FileInputStream 转成 InputStreamReader
//2、指定编码 utf-8
//3、把 InputStreamReader 传入 BufferedReader
BufferedReader br = new BufferedReader(isr);
//将2、3和在一起。
//BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),"utf-8"));
//4、读取
String s = br.readLine();
System.out.println("读取的内容:"+s);
br.close();
}
OutputStreamWrite
public static void main(String[] args) throws Exception{
String filePath = "F:\\hsp.txt";
String charSet = "utf-8";
//FileOutputStream转换成OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath),charSet);
osw.write("hi, 可靠");
osw.close();
System.out.println("按照 " +charSet+"保存文件成功~" );
}
打印流
打印流只有输出流没有流
PrintStream
默认情况下输出是标准输出
Print的底层是Write
可以修改打印流的位置
public static void main(String[] args) throws IOException {
PrintStream out = System.out;
out.println("aac");
//默认情况下PrintStream的输出是标准输出,即显示器
//Print的底层使用的是write,因此我们可以直接调用Write进行打印/输出。
out.write("你好".getBytes(StandardCharsets.UTF_8));
out.close();
//我们可以修改打印流输出的位置
//将输出位置修改为F:\\aa.txt文件
System.setOut(new PrintStream("F:\\aa.txt"));
System.out.println("hellow");
}
Propereties类
mysql.properties文件
ip=11.22.33
user=aa
pwd=123
load:加载配置文件的键值对到Properties对象。
list:将数据显示到指定设备。
getProperty(key):根据键获取值。
setProperty(key,value):设置键值对到Properties对象
store:将Properties中的键值对存储到配置文件,再idea中,保存信息到配置文件,如果含有中文,会存储为unicode码。
1
读取文件
读取文件并得到ip,user,pwd
split是用来切分的函数
s="ip=12=23"
String[] split = s.split("=");
通过“="进行切分。此时split[0]=ip,split[1]=12,split[2]=23。
public static void main(String[] args) throws IOException {
//读取mysql.properties文件
BufferedReader br = new BufferedReader(new FileReader("src\\mysql.properties"));
String line="";
while((line = br.readLine()) != null){
String[] split = line.split("=");
if("ip".equals(split[0])){
System.out.println(split[0]+"值是:"+split[1]);
}
}
br.close();
}
2
根据key,获取对应值
public static void main(String[] args) throws IOException {
//使用Properties类,读取mysql.properties文件
//1、创建Properties对象
Properties properties = new Properties();
//2、加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
//3、把k-v显示再控制台
properties.list(System.out);
//4、根据key 获取对应值
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println("用户名="+user);
System.out.println("密码="+pwd);
}
3
创建,修改
public static void main(String[] args) throws IOException {
//使用Properties类创建,配置文件。修改配置文件的内容。
//创建(setProperty()方法如果没有key是创建,如果有key是创建)
Properties properties = new Properties();
properties.setProperty("ip","11.23");
properties.setProperty("user","小红");
properties.setProperty("pwd","1123");
properties.setProperty("pwd","11");//如果没有pwd是创建,如果有是修改pwd的值。
properties.store(new FileOutputStream("src\\mysql2.properties"),"utf8");
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?