目录
1.文件
-
文件:就是保存数据的地方,(jpg,mp4,txt……)
-
流:数据在数据源(文件)和程序(内存)之间经历的路径
常用的文件操作
相关方法
-
new File(String pathname) // 根据路径构建一个File对象
-
new File(File parent,String child) // 根据父目录文件+子路径构建
-
new File(String parent,String child)// 根据父目录+子路径构建
-
createNewFile()将文件写入硬盘
测试代码
package com.pc.file;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
//创建文件
public class FileCreate {
public static void main(String[] args) {
}
@Test
//方式一:new File(String pathname) // 根据路径构建一个File对象
public void create01(){
String filePath="d:\\a1.txt";
File file=new File(filePath);
try {
file.createNewFile();
System.out.println("方式一创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
//方式二:new File(File parent,String child) // 根据父目录文件+子路径构建
public void create02(){
File parentFile = new File("d:\\"); //父目录文件
String fileName="a2.txt";
File file = new File(parentFile, fileName);
try {
file.createNewFile();
System.out.println("方式二成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
//方式三:new File(String parent,String child)// 根据父目录+子路径构建
public void create03(){
String parentPath="d:\\";
String childPath="a3.txt";
File file = new File(parentPath, childPath);
try {
file.createNewFile(); //创建文件!
System.out.println("方式三创建成功");
} catch (IOException e) {
e.printStackTrace();
}
}
}
获取文件的相关信息,常用方法
System.out.println("文件名字:"+file.getName());
System.out.println("文件绝对路径:"+file.getAbsolutePath());
System.out.println("文件父级目录:"+file.getParent());
System.out.println("文件的大小(字节):"+file.length());
System.out.println("文件是否存在:"+file.exists());
System.out.println("是不是一个文件:"+file.isFile());
System.out.println("是不是一个目录:"+file.isDirectory());
目录的操作
-
file.delete()
-
file.mkdir()和file.mkdirs()
package com.pc.file;
import org.junit.Test;
import java.io.File;
public class Directory {
public static void main(String[] args) {
}
//判断d:\\a1.txt是否存在,如果存在就删除
@Test
public void m1() {
String filePath = "d:\\a1.txt";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println(filePath + "删除成功!");
} else {
System.out.println(filePath + "删除失败");
}
} else {
System.out.println("该文件不存在");
}
}
//判断判断 d:\\demo02是否存在,存在就删除,否则提示不存在
//在java编程中,目录也被当作文件
@Test
public void m2() {
String filePath = "d:\\demo02";
File file = new File(filePath);
if (file.exists()) {
if (file.delete()) {
System.out.println(filePath + "删除成功!");
} else {
System.out.println(filePath + "删除失败");
}
} else {
System.out.println("该目录不存在");
}
}
//判断判断 d:\demo\a\b\c 是否存在,存在就提示存在,否则就创建
@Test
public void m3() {
String directoryPath = "d:\\demo\\a\\b\\c";
File file = new File(directoryPath);
if (file.exists()) {
System.out.println(directoryPath + "存在");
} else {
if(file.mkdirs()){ //mkdir()只适用于创建单级目录,多级不可用
System.out.println(directoryPath+"创建成功");
}else {
System.out.println(directoryPath+"创建失败");
}
}
}
}
2.IO流原理以及流的分类
JAVA IO原理
-
input:读取外部数据到程序内存中
-
output:将程序内存输出到硬盘中
流的分类
-
字节流(8bit)/字符流(按字节,主要看编码格式!)
-
输入流/输出流
-
节点流/处理流/包装流
(抽象基类) | 字符流 | 字节流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
简单的实现复制
package com.pc.outputstream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//完成文件拷贝
public class FileCopy {
public static void main(String[] args) {
//1.创建文件的输入流,将文件读入到程序
//2.创建文件的输出路,将文件输出到指定位置
String srcPath = "d:\\left.png";
String destPath = "receive.png";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream(srcPath);
fileOutputStream = new FileOutputStream(destPath);
byte[] buffer = new byte[1024];
int len;
while ((len = fileInputStream.read(buffer)) != -1) {
//读取到后,就写入到文件
//边读边写!
fileOutputStream.write(buffer, 0, len);
}
System.out.println("拷贝成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
}
3.节点流和处理流
-
节点流:可以从一个特定的数据源读写数据,如FileReader,FileWriter
-
处理流(包装流):是连接已存在的流(节点流或处理流)之上,为程序提供更强大的读写功能,如BufferedReader、BufferedWriter
节点流和处理流的区别和联系
-
节点流是底层流,直接跟数据源相接
-
处理流包装节点流,可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出
-
处理流对节点流进行包装,使用了修饰器设计模式,不会与数据源相连
-
处理流相当于一个工厂,把节点流这个物品进行包装装修
处理流注意: 只用关闭最外层的流即可!会调用函数自动关闭底层流
对象流
序列号和反序列化
-
序列化:保存数据时,保存数据类型和数据的值
-
反序列化:恢复数据的值和数据类型
-
需要让某个对象支持序列化机制,必须实现两个接口之一:
-
Serializable (标记接口,不用实现方法)一般采用这个接口
-
Externalizable (一定要实现两个方法)
-
exp:ObjectOutputStream写入
package com.pc.outputstream;
import java.io.*;
public class TestObjectOutStream {
public static void main(String[] args) throws IOException {
//序列化后,保存的文本格式不是存文本,而是按他的格式来保存
String filePath="d:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据到 e:data.dat
oos.writeInt(100);// int->Integer (实现了Serializable接口)
oos.writeBoolean(true);// boolean->Boolean (实现了Serializable接口)
oos.writeChar('a');// char -> Character (实现了Serializable接口)
oos.writeDouble(2.9);
oos.writeUTF("潘驰"); // String (实现了Serializable接口)
//保存一个dog对象
oos.writeObject(new Dog("旺财",10));
oos.close();
System.out.println("数据保存完毕");
}
}
//必须实现Serializable才可以进行IO
class Dog implements Serializable {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
- 查看data.dat文件
w d a@333333 娼橀┌sr com.pc.outputstream.Dog耻痄 I ageL namet Ljava/lang/String;xp
t 鏃鸿储
package com.pc.inputstream;
import com.pc.outputstream.Dog;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class TestObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath = "d:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
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());
Object dog = ois.readObject();
System.out.println("运行类型:" + dog.getClass());
System.out.println("dog信息:" + dog);//底层类型转换 object --> dog
/**需要注意的细节:
* 1.如果我们希望调用Dog的方法,需要向下专项
* 2.需要我们将Dog类的定义,拷贝到可以引用的位置
*
* */
Dog dog2=(Dog) dog;
System.out.println(dog2.getName());
//关闭
ois.close();
}
}
一些细节
-
ObjectInputStream读出,注意一定要和写入顺序一致,否则会乱码
-
要求序列化的对象必须实现Serializable(一般用这个)或Externalizable接口
-
序列化的类中,建议添加SerialVersionUID,为了提高版本的兼容性
-
序列化对象时,默认将里面所有的对象都进行序列化,除了static和transient修饰的成员
-
序列化对象时,要求里面的属性类型也都要实现序列化接口
-
序列化可以继承,若某类实现了序列化,则它的所有子类也默认实现了序列化
转换流
读出不同编码格式的中文
package com.pc.transformation;
import java.io.*;
public class CodeQuestion {
public static void main(String[] args) throws IOException {
//如果编码不一致
String filePath="d:\\a.txt"; //a.txt是国标码gbk
//使用InputStreamReader,转换流,再用bufferedReader进行包装
BufferedReader br = new BufferedReader(new InputStreamReader
(new FileInputStream(filePath), "GBK")); //这里可以指定编码集
String s;
while ((s=br.readLine())!=null){
System.out.println(s);
}
}
}
4.properties类
properties是一种配置文件,java中有对应的properties类来处理这种配置文件
用properties类读写mysql.properties类代码如下:
package com.pc.properties;
import java.io.*;
import java.util.Properties;
public class TestProperties {
public static void main(String[] args) throws IOException {
String filePath="src\\mysql.properties";
//读
Properties properties = new Properties();
properties.load(new FileReader(filePath));
properties.list(System.out);
//改
Properties properties1=new Properties();
properties1.setProperty("charset","utf-8");
properties1.setProperty("user","汤姆");
properties1.setProperty("pwd","12344f");
properties1.store(new FileOutputStream("src\\mysql2.properties"),null);
System.out.println("保存成功!");
}
}