为什么需要IO流?
在我们运行程序的时候,总是会出现程序运行结束,然后数据被清除的现象。
这样我们就无法保存数据,以便下一次使用了。其次如果有大量数据我们都需要手动输入。
如果有一个介质能保存数据,需要的时候能取出来的话。那么会非常方便,大大提高工作效率。
为什么是流?
文件的主要操作就是程序和外存来回运东西的一个过程,这里我们可以知道如果文件的引入是为了更加方便地存取数据的话。
那么就意味着最常见、最主要的两种操作就是存数据和取数据。
将我们的数据作为主体的话,那么“流”,一定是一个非常重要的媒介。“流” ,
扮演的角色就像的产品和客户之间的外卖员。
如果没有外卖员的话,虽然在生活中即使没有外卖员也能自己取,但是这里只是强调“流”作用,总结一句话就是“搬运工”。
何为 IO
I是Input 的缩写,O是Output 的缩写 。
前面我们知道文件是以流的形式来操作的,那么我们有一点有点拗口,或者有点不好理解的概念就是
什么是数据的输入,什么是文件的输出。我们可能觉得是文件主体,不是文件保存数据吗,
应该是向文件输入数据对吧,将文件的数据输出到程序中对吧,但是事实恰好相反!
这是为什么呢 ? 因为我们是以程序为主体,保存的数据的一样还是能够交给程序处理。所以我们一定要把
程序当作我们主体。正确的理解方式是将数据输入到程序中,将数据输出到文件当中。
这个操作发生在内存和外存之间。
通过这个图我们能够清楚形象的看到java程序与文件之间的关系 , 注意这个流的定义 。 、
关键词 “路径” , 一语点出了流的本质就是媒介的作用,
并且清晰的指出了数据在文件与程序之间流动的关系。
常见的文件操作
new File(String pathname) // 根据路径创建一个File对象
new File(File parent , String child) // 根据父类文件 + 子路径目录
new File(String parent , String child) // 根据父目录 + 子路径构建
createNewFile 创建新文件
这里我们解读一下这个 new File 其实就是 在内存里面生成指针 , 然后指向磁盘里面的实际物理空间
其实这个还是存在问题的, 因为Java是在虚拟机上跑,应该拿不到实际物理地址。但是暂时这么理解,正确性还需要经过验证!!!
createNewFile 方法 才是真正创建一个文件的方法。new File 只是创建一个对象!
import org.junit.Test;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
@SuppressWarnings("all")
public class FileInformation {
private String filepath = "D:\\news1.txt";
private File file = new File(filepath);
/**
* 创建文件
*/
@Test
public void create() {
try {
if(file.createNewFile())
System.out.println("文件创建成功");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 获取绝对路径
*/
@Test
public void getAbsoPath(){
System.out.println("文件绝对路径 = " + file.getAbsolutePath());
}
/**
* 获取上级目录
*/
@Test
public void getParent(){
System.out.println("文件上级路径 = " + file.getParent());
}
/**
* 文件的长度 , 按字节大小算 . 如果字符编码是 UTF-8 那么英文字符 1 字节 , 中文字符是 3 字节 .
*/
@Test
public void length(){
System.out.println("文件长度 = " + file.length());
}
/**
* exists 判断文件是否存在
*/
@Test
public void exists(){
if( file.exists() ) {
System.out.println("文件存在");
}else{
System.out.println("文件不存在");
}
}
/**
* 文件是不是一个目录 , 目录使用特殊的文件
*/
@Test
public void isDirectory(){
if( file.isDirectory() ){
System.out.println(file.getName() + "是一个文件目录");
}else{
System.out.println("该文件不是一个目录");
}
}
/**
* 该指向的对象是不是一个文件
*/
@Test
public void isFile(){
if(file.isFile()){
System.out.println("指向的对象是文件");
}
else{
System.out.println("该指向的对象不是一个文件");
}
}
}
上面是我们对文件基本知识以及获取文件基本信息的介绍
IO流原理及其流的分类
原理
1、I/O 是input/Output 的缩写 , I/O 技术是非常实用的技术 , 用于处理数据传输。如读/写文件,网络通讯等。
2、Java程序中,对于数据的输入/输出操作以“流”的方式进行。
3、Java.io 包下提供了各种“流”类和接口 , 用以获取不同类型的数据 , 并通过方法输入或输出数据
4、输入input: 读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
5、输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。
流的分类
1、 按照操作数据单元不同分为:字节流(8 bit) 二进制文件 ,字符流(按字符)文本文件 二进制文件主要是音频文件 2、按数据流的流向不同分为:输入流、输出流 3、按流的角色的不同分为:节点流,处理流/包装流
抽象基类 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer
1) Java 的IO流共涉及40多个类 , 实际上非常规则 ,都是从如上4个抽象基类派生出来的
2) 由这四个类派生出来的子类名称都是以其父类名作为子类的后缀
图中的是基类(父类)
FileInputStream
文件输入流
```
@Test
public void InputStream(){
FileInputStream fileInputStream = null;
int length = 20;
int data = 0;
byte [] by = new byte[length];
try {
fileInputStream = new FileInputStream(filepath);
// fileInputStream.read(by); 如果读取完了 , 返回 -1 .
// 注意读取中文的时候, 因为我们字符编码是UTF-8 , 英文是1字节 , 中文是3字节 .
// 所以读取中文的时候很可能出现乱码。
while((data = fileInputStream.read()) != -1)
System.out.print((char)data);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
/* 如果你想每次都是追加数据, 而不是覆写文件所有数据的话 , 你可以这么做.
fileInputStream = new FileInputStream(filepath , true);
*/
奇怪的现象
while((data = fileInputStream.read()) != -1)
System.out.print((char)data);
// 这样读取中文是乱码
/--------------------------------------------------------------------------------------/
int RealityLength = fileInputStream.read(by); // 如果读取完了 , 返回 -1 .
System.out.print(new String(by, 0 , RealityLength));
// 这样读取中文是原样显示
不是很清楚这的原因
1)OutputStream
@Test
public void output(){
FileOutputStream fileOutputStream = null ;
String name = "肖宇文";
try {
fileOutputStream = new FileOutputStream(filepath);
fileOutputStream.write(name.getBytes()); // 一定要注意这个方法哦, 很方便。
//fileOutputStream.write('1');
// 注意写入 数字 1 , 那么就是对应 ASCII码 1 , 字符 1 , 那么肯定就是对应 ‘1’ 呗。
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
注意关闭文件
刚刚我们发现其实 FileInputStream 读入字符串是通过用byte 数组装 , 然后 创建String 对象来输出数据的字符串形式。FileOutputStream ,如果要写入一个字符串那么就是通过"String".getbyte 方法, 写入文件。
文件拷贝
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@SuppressWarnings("all")
public class Main {
/*
实现将图片"考拉"的文件拷贝到另外一个文件 "others"
*/
public static void main(String[] args) {
new Main().copy();
}
public void copy(){
String filepath = "d:\\kaola.jpg";
String othersPath = "d:\\kaola2.jpg";
int realLength = 0;
String InputString = "";
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
byte [] bytes = new byte[1024];
File file = new File(filepath);
try {
fileInputStream = new FileInputStream(filepath);
fileOutputStream = new FileOutputStream(othersPath);
while((realLength = fileInputStream.read(bytes)) != -1)
fileOutputStream.write(bytes);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
关闭文件流
FileReader
这是一个Reader 的子类 主要使用的方法就是 read() , 单个字符读取返回int 形式 ,读取完则 返回 -1. 还有它的重载 read(buf , 0 , realLength) , 将内容从[0 , realLength) 读取到buf 里面 读取完则返回 -1.
import java.io.FileReader;
import java.io.IOException;
@SuppressWarnings("all")
public class FileReader_ {
public static void main(String[] args) {
String filePath = "d:\\hello.txt";
FileReader reader = null;
int length = 20;
int data = 0 ;
char [] buf = new char[length];
try {
reader = new FileReader(filePath);
/* while( ( data = reader.read()) != -1 ) // 单个字符读取
System.out.print((char)data);
*/
// 装进数组里面处理
int realLength = 0;
while( (realLength = reader.read(buf)) != -1)
System.out.print(new String(buf , 0 , realLength));
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
} 注意关闭文件流
FileReader
import java.io.FileReader;
import java.io.IOException;
@SuppressWarnings("all")
public class FileReader_ {
public static void main(String[] args) {
String filePath = "d:\\hello.txt";
FileReader reader = null;
int length = 20;
int data = 0 ;
char [] buf = new char[length];
try {
reader = new FileReader(filePath);
/* while( ( data = reader.read()) != -1 ) // 单个字符读取
System.out.print((char)data);
*/
// 装进数组里面处理 , 批量处理 .
int realLength = 0;
while( (realLength = reader.read(buf)) != -1)
System.out.print(new String(buf , 0 , realLength));
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
FileReader 作为Reader 的重要子类 , 我其实就是两个方法 或者说一个方法 . 那就是 read() 但是注意这是按字符处理 , 适合处理文本文件 .所以你可以注意到 , 我用的是char 数组装的.还是需要 new String() 去输出它的字符串形式 , 因为你不是每次读取数据都能读满整个数组 , 所以需要限制一下每次输出的长度.如果是返回当个字符的的话 , 那么返回的是一个int 类型的数据. 所以这意味着你可能得强制转化一下.
Filewriter
import java.io.FileWriter;
import java.io.IOException;
public class FileWriter__ {
public static void main(String[] args) {
String filePath = "d:\\hello.txt";
FileWriter fileWriter = null ;
int length = 20;
String str = "肖宇文";
try {
fileWriter = new FileWriter(filePath);
fileWriter.write('X');
fileWriter.write(str , 0 , str.length());
fileWriter.write(str.toCharArray() , 0 , str.length());
fileWriter.write(0); // 按照ASCII码的 形式写入的 , 不是字符 '0'.
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
fileWriter.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
注意一定要关流!!! 不关流 , 无法保存数据. 养成习惯 , 创建一个流 , 那么就需要现在 Fianlly 里面关流.
封装流/处理流
在讲这个BufferedReader 之前 , 我先讲一个非常重要的设计模式 , 也是BufferedReader 的实现核心思想.
封装流顾名思义就是封装了流嘛 , 封装了什么流呢? Reader子类的流 , 它的作用就是中间商. 集成了所有Reader子类.
这个图非常形象 , 它的本质就是将 FileReader 、 CharArrayReader 、StringReader………… 等等 封装进 BufferedReader . 说的直白就是 Reader 作为抽象父类 , 里面写的抽象方法read(read()方法只是举个例子,可能还有很多别的方法) ,然后给Reader的子类去重写,就可以实现统一了。这为包装流奠定了重要的基础。
我们可以看到这个里面有一个Reader in , 这个会用在构造器里面,去引用封装的节点流. 其实就是多态的运用.父类没有的方法,引用编译类型是父类的 , 引用的对象的运行类型是子类的. 父类的引用是调不了子类的方法,但是父类作为抽象类将子类那些实现功能的方法都做成了抽象方法. 这样将父类的节点流封装进处理流就可以正常使用对应方法了. 这样就实现了封装流(处理流)。 本质上就是多态的动态绑定!!! 这样的几句话可能基础很好也不能随随便便的看懂 , 可以多找对应的视频 , 看看源码 有助于更加深刻的理解.
好了 , 开始讲封装流BufferedReader!!!
使用就比较简单了,下面看代码即可。
代码
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@SuppressWarnings("all")
public class BufferedReader_ {
public static void main(String[] args) {
String filePath = "d:\\hello.txt";
BufferedReader bufferedReader = null ;
FileReader fileReader ;
int MaxLength = 1024;
try {
String line = "";
fileReader = new FileReader(filePath);
bufferedReader = new BufferedReader(fileReader);
// fileReader 是我们的节点流
// bufferedReader 是我们的封装流
// 第一种方法
while((line = bufferedReader.readLine()) != null )
System.out.println(line);
// 第二种方法
// char [] chArr = new char[MaxLength];
// int len = bufferedReader.read(chArr);
// System.out.println(new String(chArr, 0 , len));
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
BufferedWriter
简单的方法的调用 , 代码如下
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
@SuppressWarnings("all")
public class BufferedWriter_ {
public static void main(String[] args) {
String filePath = "d:\\hello.txt";
String writeContext = "xyw_66";
FileWriter fileWriter = null;
BufferedWriter bufferedWriter = null;
try {
fileWriter = new FileWriter(filePath , true);
bufferedWriter = new BufferedWriter(fileWriter );
bufferedWriter.write(writeContext);
bufferedWriter.write(writeContext + writeContext);
bufferedWriter.write('6');
bufferedWriter.write('6');
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
记住关流只需要关封装流即可 , 底层会直接关掉节点流 .
利用封装流进行文件拷贝
@Test
public void output(){
FileOutputStream fileOutputStream = null ;
String name = "肖宇文";
try {
fileOutputStream = new FileOutputStream(filepath);
fileOutputStream.write(name.getBytes());
//fileOutputStream.write('1');
// 注意写入 数字 1 , 那么就是对应 ASCII码 1 , 字符 1 , 那么肯定就是对应 ‘1’ 呗。
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
fileOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
字节流实现文件拷贝
代码如下:
import java.io.*;
public class BufferedOutStream_ {
public static void main(String[] args) {
String source = "d:\\kaola.jpg";
String destination = "d:\\kaola2.jpg";
BufferedInputStream bufferedInputStream = null ;
BufferedOutputStream bufferedOutputStream = null;
try {
int realLength = 0;
byte [] by = new byte[1024];
bufferedInputStream = new BufferedInputStream(new FileInputStream(source));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destination));
while((realLength = bufferedInputStream.read(by)) != -1)
bufferedOutputStream.write(by ,0 , realLength);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
bufferedInputStream.close();
bufferedOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
ObjectInputStream
为什么需要对象处理流?
我们很多时候需要保存的数据不是一个简单100, 而是一个对象的所有数据.并且很多时候我们保存的数据,
看起来是一个数值,比如存入100 . 但是明显你不知道是存入的字符串还是int类型的数值。
这时候为了满足我们不仅要保存数值还要保存数据类型的需求。所以我们需要对象处理流!
如何将保存数据,并且保存数据的数据类型呢 ?
将数据的数值和数据类型都保存到文件的操作叫 “序列化” 。
恢复数据时,恢复数据的值和数据类型这种行为就称为“反序列化”。
想要序列化和反序列化,只需要让存入的对象和其对象对应的属性实现Serializable、
Externalizable 其中一个接口即可。
推荐实现Serializable 接口, 因为这个就是一个标记接口,没有任何方法。
这是一个处理流还是节点流呢 ?
我们通过这个ObjectInputStream 构造器我们可以发现这是一个处理流.
那么它就是一个集成了InputStream子类的封装流
存储数据代码演示
代码有点麻烦 ,下面我放的代码需要仔细看.看不懂的,可以进入视频传送门。0629_韩顺平Java_ObjectOutputStream_哔哩哔哩_bilibili
package OutputStream_;
import java.io.*;
public class ObjectOutputStream_ {
public static void main(String[] args) {
String filePath = "d:\\hello.txt";
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filePath));
// 写入一个对象
oos.writeObject(new Dog("小黄 ", 3 , "白"));
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
oos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
/————————————————————————————————————————————————————————————————————————————————————/
package OutputStream_;
import java.io.Serializable;
@SuppressWarnings("all")
public class Dog implements Serializable {
private String name ;
private int age;
private String color;
private Master master ;
public Dog(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
this.master = new 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;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Master getMaster() {
return master;
}
public void setMaster(Master master) {
this.master = master;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
", master=" + master +
'}';
}
}
/——————————————————————————————————————————————————————————————————————————————————/
package InputStream_;
import OutputStream_.Dog;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
public class ObjectInputStream_ {
public static void main(String[] args) throws Exception {
String filePath = "d:\\hello.txt";
ObjectInputStream ois = null;
ArrayList<Dog> dogList = new ArrayList<>();
try {
ois = new ObjectInputStream(new FileInputStream(filePath));
Dog dog = (Dog)( ois.readObject());
dogList.add(dog);
for(Dog dogs : dogList)
System.out.println(dogs);
} catch (Exception e) {
throw new Exception(e);
} finally {
try {
ois.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
/—————————————————————————————————————————————————————————————————————————————————————————/
package OutputStream_;
import java.io.Serializable;
public class Master implements Serializable {
}
注意看包名, 有的类不是同一个包下面的。
对象处理流的注意事项和细节说明
1)读写顺序要一致 2)要求序列化和反序列化对象, 需要实现Serializable 3)序列化的类中建议添加SerialVersionUID , 为了提升版本兼容性 这个解释一下就是你在一个将一个类序列化了之后, 你再在这个类里面加入新的属性 编译器不会视作是两个不同的类 4)序列化对象时, 默认将所有的属性都序列化 ,但是static 或 transient 修饰的成员除外 5)序列化对象时 , 要求里面的类型也需要实现序列化接口. 意思就是 假如这个类里面由String , int , char …… 组成. 那么这些属性都需要能序列化, 更加直白一点就是需要实现Serializable 6)序列化具备可继承性,也就是当某个类继承了已经实现可序列化接口的类,那么这个这个类就作为了子类。 这时这个子类也可以序列化
标准输入输出流
@SuppressWarnings("all")
public class Main {
public static void main(String[] args) {
// public static final InputStream in = null;
System.out.println("System.in 的编译类型是 InputStream");
System.out.println("运行类型是" + System.in.getClass());
System.out.println();
// public static final PrintStream out = null;
System.out.println("System.out 的 编译类型是 PrintStream");
System.out.println("运行类型是 " + System.out.getClass());
}
}
输出内容:
System.in 的编译类型是 InputStream
运行类型是class java.io.BufferedInputStream
System.out 的 编译类型是 PrintStream
运行类型是 class java.io.PrintStream
我们所熟悉的System.out 是我们的标准输出流 , 将内容输出到控制台上 我们所熟悉的System.in 是我们的标准输入流 , 读取我们输入在控制台输入的内容
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
System.out.println(str);
读取数据 , 输出数据。
转换流
我们为什么需要转换流 ?
我们知道对于Java编译器 , 和存储数据的文件可能编码是不一致的。以IDEA为例,其标准编码是UTF-8 , 但是文本文件的字符编码可能是Gbk。读取数据的时候,就需要按照文件的存储数据的文件编码读取数据。不然就会出现乱码。所以我们去读取文件数据的时候,需要转化流按照文件对应编码去读取。存入数据的时候也是,我们需要按照文件本身的文件编码存入,所以需要转换流去完成。
我们什么是转换流 ?
常见的转换流是 InputStreamReader 、 OutputStreamWriter。
将字节流转化成字符流输入 , 一般这种情况都是需要显示中文的情况。因为显示乱码 , 所以需要转换一下文件编码。 其次输入的情况,一般这种情况可能也是需要输入中文 , 所以需要重新设置文件编码。
类图(只展示两种,其他类似)
其实看起来非常绕 , 或者我没讲清楚.但是用起来是非常方便 ,简单 。
import java.io.*;
@SuppressWarnings("all")
public class InputStreamReader__ {
public static void main(String[] args) throws IOException {
String filePath = "d:\\hello.txt";
String fileCode = "gbk";
int arrSize = 1024;
int realLength = 0 ;
char [] arr = new char[arrSize];
FileInputStream fileInputStream = new FileInputStream(filePath);
InputStreamReader isr = new InputStreamReader(fileInputStream, fileCode);
BufferedReader buf = new BufferedReader(isr);
while( ( realLength = buf.read(arr)) != -1)
System.out.println(new String(arr , 0 , realLength));
}
}
这段代码主要做的事情就是把 FileInputStream 包装进 InputStreamReader , 然后再将InputStreamReader,封装进 BufferedReader. 此前我已经将文件编码设置成gdk . 然后我的IDEA 编码是 UTF-8 。我现在使用的gdk 码的方式去读取文件。
public class BufferedReader_ {
public static void main(String[] args) {
String filePath = "d:\\hello.txt";
BufferedReader bufferedReader = null ;
FileReader fileReader ;
int MaxLength = 1024;
try {
String line = "";
fileReader = new FileReader(filePath);
bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null )
System.out.println(line);
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
如果你拿上面这段代码去读取同一个文本文件, 会出现乱码 , 已亲测 。
import java.io.*;
public class OutputStreamWriter__ {
public static void main(String[] args) throws IOException {
String filePath ="d:\\hello.txt";
String fileCode = "gbk";
FileOutputStream fileOutputStream = new FileOutputStream(filePath , true);
OutputStreamWriter owr = new OutputStreamWriter(fileOutputStream, fileCode);
BufferedWriter bwf = new BufferedWriter(owr);
bwf.write("是啥子");
bwf.close();
}
}
读取文件 , 为什么需要BufferedWriter 呢 , 为了方便统一使用而已 。因为我们知道BufferedWriter 集成了所有的Reader 的子类 , 所以使用这个我想应该是为了方便操作.
printStream
就是一个打印类 , 直接贴代码即可。
import java.io.IOException;
import java.io.PrintStream;
public class PrintStream__ {
public static void main(String[] args) throws IOException {
String filePath = "d:\\hello.txt";
PrintStream print = System.out;
print.println("我是小猪");
print.close();
// 将数据输出到文件当中去
System.setOut(new PrintStream(filePath));
print.write("我是小猪".getBytes());
}
}
这是类其实可能用的不是那么多, 就是常用的接收、打印方法.
Properties
Properties 主要是对配置文件进行操作 , 没讲什么知识点主要是方法如何使用。
不使用propertise 操作配置文件
import java.io.*;
public class Properties1_ {
public static void main(String[] args) throws IOException {
String filePath = "D:\\TestObject\\IOStream\\src\\mysql.properties";
int maxSize = 1024;
int realLength ;
byte [] by = new byte[maxSize];
BufferedInputStream bos = null ;
bos = new BufferedInputStream(new FileInputStream(filePath));
while((realLength = bos.read(by)) != -1)
System.out.println(new String(by, 0, realLength));
}
}
使用propertise 操作配置文件
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
@SuppressWarnings("all")
public class Properties2_ {
public static void main(String[] args) throws IOException {
String filePath = "D:\\TestObject\\IOStream\\src\\mysql.properties";
Properties properties = new Properties();
// 加载指定配置文件 load 导入 , 加载的意思.
properties.load(new FileReader(filePath));
// 把k-v 实现到控制台
properties.list(System.out);
// 根据key 获得对应的 vuale
String ip = properties.getProperty("ip");
System.out.println("用户的ip是 " + ip);
System.out.println("用户名是 " + properties.getProperty("user"));
}
}
/----------------------------------------------------------------------------------/
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class properties3_ {
public static void main(String[] args) throws IOException {
String filePath = "D:\\TestObject\\IOStream\\src\\mysql.properties";
Properties properties = new Properties();
properties.setProperty("charset" , "UTF-8");
properties.setProperty("user" , "汤姆");
// IDEA 存储中文的时候存储的是汤姆的unicode 码 !
// 将k - v 存储到配置文件中
properties.store(new FileWriter(filePath) , "hello, world");
// 这个hello , world 是一个注释 , 一般我们直接写null
// 希望修改配置文件中的变量 , 就可以直接使用 store 方法 , 直接覆盖即可
System.out.println("保存成功!");
}
}
目前还没发现在不覆写的情况下 ,通过key , 修改其对应vuale. 目前还是太菜, 3天学完IO还是有点慢了。连着看课写博客代码,现在已经是2023/7/13/23:17 , 休息了。