IO
- 1.文件流
- 2.常用的文件操作
- (1)根据路径构建一个File对象
- (2)根据父目录文件+子路径构建
- (3)根据父目录+子路径构建
- (4)获取文件相关信息
- (5)目录的操作和文件的删除
- 3.IO流原理及流的分类
- (1)流的分类
- (2)字节输入流(InputStream)
- (3)字节输出流(FileOutputStream)
- (4)文件拷贝
- (5)字符输入流(FileReader)
- (6)字符输出流(FileWriter)
- 4.节点流和处理流
- (1)节点流
- (2)处理流(包装流)
- (3)节点流和处理流的区别和联系
- (4)BufferedReader
- (5)BufferedWriter
- (6)完成文本文件拷贝
- (7)BufferedInputStream和BufferedOutputStream实现图片拷贝
- 5.对象处理流
- (1)ObjectOutputStream
- (2)ObjectInputStream
- (3)对象处理流使用细节
- 6.标准输入输出流
- 7.转换流
- (1)InputStreamReader
- (2)OutputStreamWriter
- 8.打印流
- (1)PrintStream(字节流)
- (2)PrintWriter(字符流)
- 9.Properties类
1.文件流
2.常用的文件操作
(1)根据路径构建一个File对象
public class CreateFile {
public static void main(String[] args) {
String filePath="D:\\io\\hello.txt";
create1(filePath);
}
//根据路径构建一个File对象
public static void create1(String filePath){
//在内存中有了一个file对象
File file = new File(filePath);
try {
file.createNewFile();//写入到磁盘对应的位置
System.out.println("文件创建成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
(2)根据父目录文件+子路径构建
//根据父目录文件+子路径构建
public static void create2(String parent,String fileName){
File parentFile = new File(parent);
File file = new File(parentFile, fileName);
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
(3)根据父目录+子路径构建
//根据父目录+子路径构建
public static void create3(String parent,String fileName){
File file = new File(parent, fileName);
try {
file.createNewFile();
System.out.println("文件创建成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
(4)获取文件相关信息
public class GetInformationInFile {
public static void main(String[] args) {
String path="d:\\io\\hello.txt";
info(path);
}
public static void info(String filePath){
//先创建文件对象
File file = new File(filePath);
//得到文件名
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());
}
}
(5)目录的操作和文件的删除
public class Directories {
public static void main(String[] args) {
//String path="D:\\io\\hello.txt";
//m1(path);
String path="D:\\io\\111";
m3(path);
}
//判断文件是否存在 如果存在就删除
public static void m1(String path){
File file = new File(path);
if (file.exists()){
if (file.delete()){
System.out.println(path+"删除成功");
}else {
System.out.println(path+"删除失败");
}
}else {
System.out.println("该文件不存在");
}
}
//判断目录是否存在 如果存在就删除
//在java编程中 目录也当作文件
public static void m2(String path){
File file = new File(path);
if (file.exists()){
if (file.delete()){
System.out.println(path+"删除成功");
}else {
System.out.println(path+"删除失败");
}
}else {
System.out.println("该目录不存在");
}
}
//判断目录是否存在 如果存在就提示存在,如果不存在就删除
public static void m3(String path){
File file = new File(path);
if (file.exists()){
System.out.println("该目录存在");
}else {
//创建多级目录
if (file.mkdirs()){
System.out.println(path+" 目录创建成功");
}else {
System.out.println(path+" 目录创失败");
}
}
}
}
3.IO流原理及流的分类
(1)流的分类
(1)按操作数据单位不同分为:字节流(保证操作二进制文件无损操作) 字符流(按字符读取,效率高,操作文本文件)
(2)按数据流的方向不同: 输入流 输出流
(3)按流的角色不同: 节点流 处理流
(2)字节输入流(InputStream)
public class test {
public static void main(String[] args) {
String path="d:\\io\\hello.txt";
readFile2(path);
}
/**
* 演示读取文件
* 单个字节读取 读取效率低
* @param path
*/
public static void readFile1(String path){
int readData=0;
FileInputStream fileInputStream=null;
try {
//创建FileInputStream对象 用于读取文件
fileInputStream = new FileInputStream(path);
//从该输入流读取一个字节的数据 如果没有输入可用 此方法将阻止
//如果返回-1 表示读取完毕
while ((readData=fileInputStream.read())!=-1){
System.out.print((char) readData+" ");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭文件流 释放资源
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
* 使用read(byte[] b)读取文件 提高效率
* @param path
*/
public static void readFile2(String path){
int readLen=0;
//字节数组
byte[] buf=new byte[8];//一次读取8个字节
FileInputStream fileInputStream=null;
try {
//创建FileInputStream对象 用于读取文件
fileInputStream = new FileInputStream(path);
//从该输入流读取buf.length字节的数据 此方法将阻塞,直到某些输入可用
//如果返回-1 表示读取完毕
//如果读取正常 返回实际读取的字节数
while ((readLen=fileInputStream.read(buf))!=-1){
System.out.println(new String(buf,0,readLen));//转换为字符串显示
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭文件流 释放资源
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
(3)字节输出流(FileOutputStream)
public class test {
public static void main(String[] args) {
String path="d:\\io\\test.txt";
writeFile(path);
}
/**
* 演示使用FileOutputStream
* 将数据写入文件中,如果该文件不存在,则创建该文件
* 当写入内容时,会覆盖原来的内容
* 如果不想覆盖:new FileOutputStream(path,true),则以追加的形式写入
* @param path
*/
public static void writeFile(String path){
//创建FileOutputStream对象
FileOutputStream fileOutputStream=null;
try {
//得到FileOutputStream对象
fileOutputStream=new FileOutputStream(path);
//写入一个字节
//fileOutputStream.write('t');
//写入字符串
//str.getBytes()->可以把字符串转为字节数组
String str="TangMeng";
fileOutputStream.write(str.getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
(4)文件拷贝
(5)字符输入流(FileReader)
public class test {
public static void main(String[] args) {
String path="d:\\io\\ha.txt";
fileReaderTest2(path);
}
/**
*使用字符输入流操作文件
* 每次读取单个字符
*/
public static void fileReaderTest(String path){
FileReader fileReader=null;
int data=0;
try {
fileReader=new FileReader(path);
//循环读取 每次读取单个字符
while ((data=fileReader.read())!=-1){
System.out.println((char) data);
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
fileReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
/**
*使用字符输入流操作文件
*使用字符数组来读取文件
*/
public static void fileReaderTest2(String path){
FileReader fileReader=null;
char[] buf=new char[8];
int readLen=0;
try {
fileReader=new FileReader(path);
//循环读取 返回的是实际读取的字符数
//如果返回-1,说明到文件结束
while ((readLen=fileReader.read(buf))!=-1){
System.out.print(new String(buf,0,readLen));
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
fileReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
(6)字符输出流(FileWriter)
FileWriter使用后必须要关闭或者刷新,才能将内容写入文件
public class test {
public static void main(String[] args) {
String path="d:\\io\\haha.txt";
fileWriterTest(path);
}
/**
*使用字符输出流操作文件
*/
public static void fileWriterTest(String path){
FileWriter fileWriter=null;
char[] chars={'a','b','c'};
try {
fileWriter=new FileWriter(path,true);
//写入单个字符
fileWriter.write('H');
//写入指定数组
fileWriter.write(chars);
//写入指定数组的指定部分
fileWriter.write("哈哈哈".toCharArray(),0,2);
//写入整个字符串
fileWriter.write("哈哈");
//写入字符串的指定部分
fileWriter.write("哈哈哈哈哈哈",4,3);
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
//fileWriter需要关闭流或者flush才能把数据真正写入到文件
try {
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
4.节点流和处理流
(1)节点流
节点流可以从一个特定的数据源读写数据
(2)处理流(包装流)
处理流封装已经存在的流,为程序提供更为强大的读写功能
性能提高:主要以增加缓冲的方式来提高输入输出效率
操作便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便
(3)节点流和处理流的区别和联系
(1)节点流是底层流/低级流,直接跟数据源相接
(2)处理流包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出
(3)处理流对节点流进行包装,使用了修饰器模式,不会直接与数据源相连
(4)BufferedReader
public class test {
public static void main(String[] args) {
String path="d:\\io\\haha.txt";
bufferReaderTest(path);
}
/**
*使用处理流操作文件
*/
public static void bufferReaderTest(String path){
BufferedReader bufferedReader=null;
try {
bufferedReader=new BufferedReader(new FileReader(path));
//读取
String line;
//bufferedReader.readLine() 按行读取 当返回null时,表示文件读取完毕
while ((line=bufferedReader.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
//关闭流 只需要关闭bufferedReader就可以了,因为底层会自动关闭节点流
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
(5)BufferedWriter
public class test {
public static void main(String[] args) {
String path="d:\\io\\haha.txt";
bufferWriterTest(path);
}
/**
*使用处理流操作文件
*/
public static void bufferWriterTest(String path) {
BufferedWriter bufferedWriter=null;
try {
bufferedWriter=new BufferedWriter(new FileWriter(path,true));
bufferedWriter.write("哈哈哈");
bufferedWriter.newLine();//插入一个和系统相关的换行符
bufferedWriter.write("哈哈哈");
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
//关闭流
try {
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
(6)完成文本文件拷贝
public class test {
public static void main(String[] args) {
String from="d:\\io\\haha.txt";
String to="d:\\io\\haha1.txt";
bufferCopyTest(from,to);
}
/**
*使用处理流拷贝文件
*/
public static void bufferCopyTest(String from,String to) {
BufferedReader bufferedReader=null;
BufferedWriter bufferedWriter=null;
String line=null;
try {
bufferedReader=new BufferedReader(new FileReader(from));
bufferedWriter=new BufferedWriter(new FileWriter(to));
//读取
//readLine()读取一行的数据 但没有都换行符
while ((line=bufferedReader.readLine())!=null){
//每读取一行 就写出
bufferedWriter.write(line);
//插入换行
bufferedWriter.newLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
//关闭流
try {
bufferedReader.close();
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
(7)BufferedInputStream和BufferedOutputStream实现图片拷贝
public class test {
public static void main(String[] args) {
String from="d:\\io\\2.jpg";
String to="d:\\io\\3.jpg";
bufferCopyTest(from,to);
}
/**
*使用处理流拷贝文件
*/
public static void bufferCopyTest(String from,String to) {
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
bis=new BufferedInputStream(new FileInputStream(from));
bos=new BufferedOutputStream(new FileOutputStream(to));
//循环读取文件,并写出到目的地
byte[] buf=new byte[1024];
int readLen=0;
//当返回-1时,就表示文件读取完毕
while ((readLen= bis.read(buf))!=-1){
bos.write(buf,0,readLen);
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
bis.close();
bos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
5.对象处理流
(1)ObjectInputStream:提供反序列化功能
(2)ObjectOutputStream:提供序列化功能
(1)ObjectOutputStream
public class test {
public static void main(String[] args) {
String path="d:\\io\\xu";
objectOutputStreamTest(path);
}
/**
*使用objectOutputStream,完成数据的序列化
* 序列化后保存的文件格式不是纯文本的,而是按照要保存的格式保存的
*/
public static void objectOutputStreamTest(String path) {
ObjectOutputStream oos=null;
try {
oos=new ObjectOutputStream(new FileOutputStream(path,true));
//序列化数据到文件中
oos.writeInt(100);//int -> Integer(实现了Serializable)
oos.writeBoolean(true);//boolean -> Boolean
oos.writeChar('a');//char -> Character
oos.writeDouble(1.8);//double -> Double
oos.writeUTF("小白");//String
//保存一个dog对象
oos.writeObject(new Dog("旺财",1));
System.out.println("保存数据完毕");
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
oos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
class Dog implements Serializable{
private String name;
private int age;
public Dog(String name,int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(2)ObjectInputStream
public class test {
public static void main(String[] args) {
String path="d:\\io\\xu";
objectInputStreamTest(path);
}
/**
*使用objectInputStream,完成数据的反序列化
*/
public static void objectInputStreamTest(String path) {
ObjectInputStream ois=null;
try {
ois=new ObjectInputStream(new FileInputStream(path));
//读取
//读取的顺序需要和保存时的顺序一致
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 dog =(Dog) ois.readObject();
System.out.println(dog);//底层:Object->dog
dog.getName();//可以调用dog类里边的方法
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} finally {
try {
ois.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
class Dog implements Serializable{
private String name;
private int age;
public Dog(String name,int age){
this.name=name;
this.age=age;
}
public String getName(){
return name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(3)对象处理流使用细节
(1)读写顺序一致
(2)要求序列化或反序列化的对象,需要实现 Serializable
(3)序列化类中建议添加SerialVersionUID,可以提高版本的兼容性。加了版本号的话,以后对该类的修改
会看做一次修改而不是当作一个新类
(4)序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
(5)序列化对象时,要求里面属性的类型也需要实现序列化接口
(6)序列化具备可继承性,如果没类实现了可序列化,则它的所有子类也已经默认实现了
6.标准输入输出流
System.in 标准输入 键盘
System.out 标准输出 显示器
7.转换流
将字节流转换为字符流
为了防止读取时出现的中文乱码问题
(1)InputStreamReader
public class test {
public static void main(String[] args) {
String path="d:\\io\\ha.txt";
inputStreamReaderTest(path);
}
/**
*使用 InputStreamReader 转换流解决中文乱码问题
* 将字节流FileInputStream 转换成字符流InputStreamReader,指定编码utf-8
*/
public static void inputStreamReaderTest(String path) {
InputStreamReader inputStreamReader=null;
BufferedReader bufferedReader=null;
try {
//将FileInputStream转为InputStreamReader,指定编码utf-8
inputStreamReader=new InputStreamReader(new FileInputStream(path),"utf-8");
//把InputStreamReader传入 BufferedReader
bufferedReader=new BufferedReader(inputStreamReader);
//读取
String s = bufferedReader.readLine();
System.out.println("读取到内容="+s);
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
//关闭流
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
(2)OutputStreamWriter
public class test {
public static void main(String[] args) {
String path="d:\\io\\ha.txt";
outputStreamWriterTest(path);
}
/**
*使用 OutputStreamWriter
* 将字节流FileOutputStream 转换成字符流OutputStreamWriter,指定编码utf-8
*/
public static void outputStreamWriterTest(String path) {
OutputStreamWriter osw=null;
try {
osw=new OutputStreamWriter(new FileOutputStream(path,true),"utf-8");
osw.write("哈哈哈,傻子");
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
osw.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
8.打印流
(1)PrintStream(字节流)
public class test {
public static void main(String[] args) {
String path="d:\\io\\ha.txt";
printStreamTest(path);
}
/**
*使用 PrintStream(字节打印流)
*/
public static void printStreamTest(String path) {
PrintStream out=System.out;
//在默认情况下,PrintStream输出数据的位置是显示器
out.print("hello!world");
//因为print的底层使用的是write,所以可以直接调用write进行打印
try {
out.write("哈哈".getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
out.close();
//可以修改打印流输出的位置
try {
System.setOut(new PrintStream(path));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
System.out.println(333);
}
}
(2)PrintWriter(字符流)
public class test {
public static void main(String[] args) {
String path="d:\\io\\ha.txt";
printWriterTest(path);
}
/**
*使用 PrintWriter(字符打印流)
*/
public static void printWriterTest(String path) {
PrintWriter printWriter=null;
//输出到控制台
printWriter=new PrintWriter(System.out);
printWriter.print("12345678");
//修改输出位置
try {
printWriter=new PrintWriter(new FileWriter(path));
} catch (IOException e) {
throw new RuntimeException(e);
}
printWriter.print("你好呀");
printWriter.close();
}
}
9.Properties类
(1)load:加载配置文件的键值对到Properties对象
(2)list:将数据显示到指定设备
(3)getProperty(key):根据键获取值
(4)setProperty(key,value):设置键值对到Properties对象
(5)store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,
会存储为unicode码
public class test {
public static void main(String[] args) {
String path="d:\\io\\ha.txt";
testProperties();
}
public static void testProperties(){
//1.创建Properties对象
Properties properties = new Properties();
//2.加载指定配置文件
try {
properties.load(new FileReader("src\\mysql.properties"));
//3.把键值对显示在控制台
properties.list(System.out);
//4.根据key获取对应的value
String name= properties.getProperty("name");
System.out.println(name);
//5.向配置文件添加内容
properties.setProperty("charset","utf8");
properties.setProperty("ha","hah");
properties.store(new FileOutputStream("src\\mysql.properties"),null);
System.out.println("保存成功");
//6.修改键值对 setProperty(key,value)方法:
//如果该文件没有对应的key,就是创建;如果有对应的key,就是修改
properties.setProperty("ha","hahahaha");
properties.store(new FileOutputStream("src\\mysql.properties"),null);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}