个人主页:https://blog.csdn.net/hello_list
今天我们来学习下java中的io部分
首先我们要知道io指的是什么,输入输出,就是输入输出流,我们在知道就是流又分为两个,输入流和输出流,再从单位上分,又分为字符流和字节流
再按功能,又分为节点流和过滤流
InputStream常用方法
int | available() 返回从该输入流中可以读取(或跳过)的字节数的估计值,而不会被下一次调用此输入流的方法阻塞。 |
---|---|
void | close() 关闭此输入流并释放与流相关联的任何系统资源。 |
void | mark(int readlimit) 标记此输入流中的当前位置。 |
boolean | markSupported() 测试这个输入流是否支持 mark 和 reset 方法。 |
abstract int | read() 从输入流读取数据的下一个字节。 |
int | read(byte[] b) 从输入流读取一些字节数,并将它们存储到缓冲区 b 。 |
int | read(byte[] b, int off, int len) 从输入流读取最多 len 字节的数据到一个字节数组。 |
void | reset() 将此流重新定位到上次在此输入流上调用 mark 方法时的位置。 |
long | skip(long n) 跳过并丢弃来自此输入流的 n 字节数据。 |
OutputStream常用方法
void | close() 关闭此输出流并释放与此流相关联的任何系统资源。 |
---|---|
void | flush() 刷新此输出流并强制任何缓冲的输出字节被写出。 |
void | write(byte[] b) 将 b.length 字节从指定的字节数组写入此输出流。 |
void | write(byte[] b, int off, int len) 从指定的字节数组写入 len 个字节,从偏移 off 开始输出到此输出流。 |
abstract | write(int b) 将指定的字节写入此输出流 |
我们最常用的是实现他们的子类,FileInputStream和FileOutputStream,我们做一个简单的应用
我们首先用FileOutputStream创建一个文件并写入内容
public class FileOutputStreamTest {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("E://hello.txt");
fileOutputStream.write("hello".getBytes());
// 刷新磁盘空间
fileOutputStream.flush();
// 关闭字节流
fileOutputStream.close();
System.out.println("文件写入成功");
}
}
效果
FileInputStream读取文件
public class FileInputStreamTest {
public static void main(String[] args) throws Exception {
File file = new File("E:\\hello.txt");
// System.out.println(file.exists());
// BufferedReader fis = new BufferedReader(new InputStreamReader(System.in));
FileInputStream fis = new FileInputStream(file);
int count = -1;
byte[] buff = new byte[1024];
while ((count = fis.read(buff)) != -1) {
System.out.println(new String(buff, 0, count,"UTF-8"));
}
fis.close();
}
}
我们还可以使用具有缓存效果的字节流:BufferedInputStream和BufferedOutputStream,具有缓存,可以提高效率
BufferedOutputStream读取文件
public class BufferedOutputStreamTest {
public static void main(String[] args) throws Exception {
// 1、创建流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E://hello.txt"));
// 2、写入文件内容
bos.write("hello,我是学习日记".getBytes());
// 3、刷新磁盘,关闭流
bos.flush();
bos.close();
System.out.println("写入文件完成");
}
}
BufferedInputStream读取文件
public class BufferedInputStreamTest01 {
public static void main(String[] args) throws Exception {
// 1、创建流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E://hello.txt"));
int len = -1;
byte[] buffer = new byte[1024];
// 2、通过流读取内容
while ((len=bis.read(buffer))!=-1){
System.out.println(new String(buffer,0,len,"UTF-8"));
}
// 3、关闭流
bis.close();
}
}
我们还可以使用对象流创建和保存对象:ObjectOutputStream和ObjectInputStream
使用ObjectOutputStream保存对象
我们首先创建一个student学生类
package com.xuexi.io;
import java.io.Serializable;
// 必须实现序列化接口
public class Student implements Serializable {
String name;
Integer age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
通过对象流可以保存对象持久化
public class ObjectOutputStreamTest {
public static void main(String[] args) throws Exception {
Student xuexi = new Student("学习日记", 18);
// 1、创建流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\hello.txt"));
// 2、写入内容
oos.writeObject(xuexi);
// 3、关闭流 close的时候会自动进行flush操作
oos.flush();
oos.close();
System.out.println("保存对象成功");
}
}
我们可以看下保存的对象是什么样子,其实可以看出来,就是我们保存的样子
还可以使用ObjectInputStream读取对象,反序列化
public class ObjectInputStreamTest {
public static void main(String[] args) throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\hello.txt"));
Student xuexi = (Student)ois.readObject();
ois.close();
System.out.println(xuexi);
}
}
可以看到读取成功对象,这样也是创建对象的一种方式
Reader和Writer这里两大接口
其实跟之前的字节流一样,我们可以直接使用FileReader和FileWriter
FileWriter写入文件
public class FileWriterTest {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("E:\\hello.txt");
fw.write("hello,我是学习日记");
fw.flush();
fw.close();
System.out.println("写入文件成功");
}
}
FileReader读取文件
public class FileReaderTest {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("E:\\hello.txt");
int len = -1;
char[] buffer = new char[1024];
while ((len = fr.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
}
fr.close();
}
}
同样我们肯定还有具有缓冲效果的字符缓冲流,可以提高读写效率:BufferedReader和BufferedWriter
BufferedWriter写入文件
public class BufferedWriterTest {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\hello.txt"));
bw.write("hello,我是学习日记");
bw.flush();
bw.close();
System.out.println("文件写入完毕");
}
}
BufferedReader读取文件
public class BufferedReaderTest {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("E:\\hello.txt"));
int len = -1;
char[] buffer = new char[1024];
while ((len = br.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
}
br.close();
}
}
ISO-8859-1收录除了ASCII外,还包括西欧、希腊语、泰语、阿拉伯语等对应的文字符号;
UTF-8:针对Unicode码表的可变长度字符编码
GB2312:简体中文
GBK:简体中文,扩充
BIG5台湾,繁体中文
PrintWriter顾名思义 打印流,支持数据原样直接打印,并且封装了print和println支持写入后换行
public class PrintWriterTest {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter pw = new PrintWriter("D:\\hello.txt");
pw.println(12);
pw.println(false);
pw.println(123.123);
pw.println('a');
pw.println("hello,我是学习日记");
pw.close();
System.out.println("文件写入完成");
}
}
我们可以看下写入内容
我们知道字符流比字节流更大,那我们也可以讲字节流转换位字符流,同时可以设置字符编码格式
我们就需要用到转换流:InputStreamReader和OutputStreamWriter
OutputStreamWriter字节流转换为字符流写入文件
public class OutputStreamWriterTest {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("E:\\hello.txt");
OutputStreamWriter osr = new OutputStreamWriter(fos,"UTF-8");
osr.write("hello,我是学习日记");
osr.flush();
osr.close();
fos.close();
System.out.println("文件写入成功");
}
}
InputStreamReader读取文件
public class OutputStreamWriterTest {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("E:\\hello.txt");
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
int len = -1;
char[] buffer = new char[1024];
while ((len = isr.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
}
isr.close();
fis.close();
}
}
看下File文件的使用,我们在之前通过流创建文件的时候就直接写好了绝对路径地址,如果文件不存在就会自动创建文件,我们可以发现其实接口里面也是帮我们new了一个File文件
使用起来呢其实都很简单,调用一些方法,参数什么的,大家可以参考着API文档去使用就可以了
这里我们再提一个FileFilter过滤器接口,顾名思义可以用来做一些过滤的操作
public class FileFilterTest {
public static void main(String[] args) {
File file = new File("E:\\MarkDown");
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".md"))
return true;
return false;
}
});
for (int i = 0; i < files.length; i++) {
System.out.println(files[i]);
}
}
}
上手试一下,然后多看着api文档调用下,就可以了,很简单,不过一定要上手哦
properties其实就是属性集合,我们经常用来做配置文件
我们可以看下有哪些方法:
Modifier and Type | Method and Description |
---|---|
String | getProperty(String key) 使用此属性列表中指定的键搜索属性。 |
String | getProperty(String key, String defaultValue) 使用此属性列表中指定的键搜索属性。 |
void | list(PrintStream out) 将此属性列表打印到指定的输出流。 |
void | list(PrintWriter out) 将此属性列表打印到指定的输出流。 |
void | load(InputStream inStream) 从输入字节流读取属性列表(键和元素对)。 |
void | load(Reader reader) 以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。 |
void | loadFromXML(InputStream in) 将指定输入流中的XML文档表示的所有属性加载到此属性表中。 |
Enumeration | propertyNames() 返回此属性列表中所有键的枚举,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
void | save(OutputStream out, String comments) 已弃用 如果在保存属性列表时发生I / O错误,此方法不会抛出IOException。 保存属性列表的store(OutputStream out, String comments) 方法是通过store(OutputStream out, String comments) 方法或storeToXML(OutputStream os, String comment) 方法。 |
Object | setProperty(String key, String value) 致电 Hashtable 方法 put 。 |
void | store(OutputStream out, String comments) 将此属性列表(键和元素对)写入此 Properties 表中,以适合于使用 load(InputStream) 方法加载到 Properties 表中的格式输出流。 |
void | store(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties 表中,以适合使用 load(Reader) 方法的格式输出到输出字符流。 |
void | storeToXML(OutputStream os, String comment) 发出表示此表中包含的所有属性的XML文档。 |
void | storeToXML(OutputStream os, String comment, String encoding) 使用指定的编码发出表示此表中包含的所有属性的XML文档。 |
Set | stringPropertyNames() 返回此属性列表中的一组键,其中键及其对应的值为字符串,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。 |
这里我们简单使用下:
public class PropertiesTest {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.setProperty("name","学习日记");
properties.setProperty("age","18");
System.out.println(properties);
Set<String> strings = properties.stringPropertyNames();
strings.forEach((e)->{
System.out.println(e);
});
// 还可以和打印流结合使用
PrintWriter pw = new PrintWriter("E:\\hello.txt");
properties.list(pw);
pw.close();
System.out.println("properties持久化成功");
// 还可以通过Store方法保存
FileOutputStream fos = new FileOutputStream("E:\\hello.properties");
properties.store(fos,"这是一个注释");
fos.close();
// 还有可以加载文件的load方法
Properties properties1 = new Properties();
FileInputStream fis = new FileInputStream("E:\\hello.properties");
properties1.load(fis);
fis.close();
System.out.println(properties1);
}
}
都看到这里了还不点个关注三连吗,后面我们还会学习java Nio Bio等,bye~