JavaIO流
IOjavascript:;
- 可以将数据从本地文件读取出来
- 可以将数据从内存保存到本地文件
概述(参照物是内存)
- I表示input,是数据从硬盘进内存的过程,称之为读。
- O表示output,是数据从内存到硬盘的过程,称之为写。
- IO的数据传输,可以看作是一种数据的流动,按照流动的方向,以内存为参照物,进行读写操作
IO流的分类
按流向分
- 输入流
- 输出流
按数据类型分
- 字节流:操作所有类型的文件,包括音频视频图片等
- 字符流:只能操作纯文本文件,包括Java文件,txt文件等
注:
- 纯文本文件:用记事本打开能读的懂,那么这样的文件就是纯文本文件
- 如果想要拷贝,一律使用字节流或者字节缓冲流
- 想要把文本文件中的数据读到内存中,请使用字符输入流
- 想要把内存中的数据写道文本文件中,请使用字符输出流
- GBK码表中一个中文2个字节,UTF-8编码格式一个中文3个字节
1. 字节流
1.1 输出流 FileOutputStream
构造方法
FileOutputStream(File file) 创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(FileDescriptor fdObj) 创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
FileOutputStream(String name) 创建文件输出流以指定的名称写入文件。
FileOutputStream(String name, boolean append) 创建文件输出流以指定的名称写入文件。
注意事项
1. 如果文件不存在,它会帮我们自动创建出来
2. 如果文件存在,会把文件清空
常用方法
- public void write(int b):将指定的字节写入此文件输出流。
注:传递一个整数时,那么实际上写入文件中的,是这个整数在码表中对应的那个字符
- public void close():关闭此文件输出流并释放与此流相关联的任何系统资源。
注:每次使用完流必须要释放资源
写入数据的三种方式
- public void write(int b):一次写入一个字节
- public void write(byte[] b):一次写一个字节数组数据
- public void write(byte[] b,int off ,int len):一次写一个字节数组的部分数据。len是表示几个
字节流实现换行和追加
- 写完数据和,加换行符。windows:\r\n,linux:\n,mac:\r
追加
- FileOutputStream(String name, boolean append) 创建文件输出流以指定的名称写入文件。
FileOutputStream fos = new FileOutputStream("D:\FileTest\b.txt",true);
- FileOutputStream(File file, boolean append) 创建文件输出流以写入由指定的 File对象表示的文件。
这俩个构造方法的第二个参数表示是否续写,如果为true则继续添加不删除原先文件的内容
提高拷贝速度的方法
字节流通过创建字节数组,可以一次读写多个数据。
- public int read(byte[] b):从输入流读取最多b.length个字节数据
返回的是读入缓冲区的总字节数,也就是实际读取字节个数
1.2字节输入流FileInputStream
- FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名
- 字节输入流读取数据的步骤
- 创建字节输入流对象
- 调用字节输入流对象的读数据方法
- 释放资源
public class FileInputStreamDemo01 {
public static void main(String[] args) throws IOException {
//创建字节输入流对象
FileInputStream fis = new FileInputStream("myByteStream\\fos.txt");
int by;
/*
fis.read():读数据
by=fis.read():把读取到的数据赋值给by
by != -1:判断读取到的数据是否是-1
*/
while ((by=fis.read())!=-1) {
System.out.print((char)by);
}
//释放资源
fis.close();
}
}
1.3 缓冲流
缓冲流是为了提供效率的,不能直接操作文件,需要传递字节流
字节缓存流BufferOutputStream
- BufferOutputStream:字节缓冲输出流
- BufferedInputStream:字节缓存输入流
构造方法:
- 字节缓冲输出流:BufferedOutPutStream(OutputStream out)
- 字节缓冲输入流:BufferedInputStream(InputStream in)
字节缓冲流仅仅是提供缓冲区,而真正的读写数据还得以考基本的字节流对象进行操作
2. 字符流
由于字节流操作中文不是特别的方便,所以Java就提供字符流
字节流读取文件,读到内存中,有可能出现乱码,导致写入的时候也可能出现乱码
概述
- 字符流 = 字节流 + 编码表
- 不管在什么表中,中文的第一个字节一定是负数
注意事项
- WIndows默认使用码表为:GBK,一个中文字符2个字节
- idea和以后工作默认使用Unicaode的UTF-8编码格式,一个中文3个字符
编码
- byte[] getBytes():使用平台默认字符集将改String编码为一系列字节,将结构存储到新的字节数组中
- byte[] getBytes(String charsetName):使用指定的字符集将改String编码为一系列字节,将结构存储到新的字节数组中
解码
- String(byte[] bytes):通过使用平台默认字符集解码指定的字节数组来构造新的String
- String(byte[] bytes,String charsetName):通过指定的字符集解码指定的字节数组来构造新的String
1.1 输出流 FileWriter
构造方法
FileWriter(File file) 给一个File对象构造一个FileWriter对象。
FileWriter(File file, boolean append) 给一个File对象构造一个FileWriter对象。
FileWriter(FileDescriptor fd) 构造与文件描述符关联的FileWriter对象。
FileWriter(String fileName) 构造一个给定文件名的FileWriter对象。
FileWriter(String fileName, boolean append) 构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。
常用方法
void write(int c)写一个字符
void write(char[] cbuf)写出一个字符数组
void write(char[ cbuf, int off, int len)写出字符数组的一部分
void write(String str)写一个字符串
void write(String str, int off, int len)写一个字符串的一部分
注意事项
1. 如果文件不存在,就创建。但是要保证父级路径存储。
2. 如果文件存在就清空
3. 写出int类型的整数,实际写出的是整数在码表上对应的字符。
4. 写出字符串数据,是吧字符串本身原样写出。
5. 每次使用完流必须要释放资源。
特殊方法
- flush():刷新流,还可以继续写数据
- close():关闭流,释放资源。但是在关闭之前会先刷新流。一旦关闭,就不能在写数据
1.2 输入流FileReader
构造方法
FileReader(File file)新的 FileReader ,给出 File读取。
FileReader(FileDescriptor fd)一个新的 FileReader ,给定 FileDescriptor读取。
FileReader(String fileName)一个新的 FileReader ,给定要读取的文件的名称。
1.3字符缓冲流
- BufferedWriter:可以将数据高效的写出
- BufferedReader:可以将数据高效的读取到内存
特有功能
BufferedWriter字符缓冲输出流
- void newLine():写一行行分隔符,行分隔符字符串由系统属性定义
BufferedReader字符缓冲输入流
- public String readLine():读一行文件。结构包括行的内容的字符串,不包括任何终止字符串,如果流的结尾已经到达,则返回null
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("day11\\a.txt"));
String line;
while ((line=br.readLine())!=null){
System.out.println(line);
}
br.close();
}
}
3.转换流
3.1字符流中和编码解码问题相关的两个类【理解】
- InputStreamReader:是从字节流到字符流的桥梁,父类是Reader
它读取字节,并使用指定的编码将其解码为字符
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
- OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer
是从字符流到字节流的桥梁,使用指定的编码将写入的字符编码为字节
它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集
3.2转换流读写数据【应用】
- 构造方法
方法名 说明
InputStreamReader(InputStream in) 使用默认字符编码创建InputStreamReader对象
InputStreamReader(InputStream in,String chatset) 使用指定的字符编码创建InputStreamReader对象
OutputStreamWriter(OutputStream out) 使用默认字符编码创建OutputStreamWriter对象
OutputStreamWriter(OutputStream out,String charset) 使用指定的字符编码创建OutputStreamWriter对象
- 代码演示
public class ConversionStreamDemo {
public static void main(String[] args) throws IOException {
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"),"GBK");
osw.write("中国");
osw.close();
//InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"));
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"),"GBK");
//一次读取一个字符数据
int ch;
while ((ch=isr.read())!=-1) {
System.out.print((char)ch);
}
isr.close();
}
}
4.对象操作流
使用一个字节序列表示一个对象
4.1对象序列化流【应用】
- 对象序列化介绍
- 对象序列化:就是将对象保存到磁盘中,或者在网络中传输对象
- 这种机制就是使用一个字节序列表示一个对象,该字节序列包含:对象的类型、对象的数据和对象中存储的属性等信息
- 字节序列写到文件之后,相当于文件中持久保存了一个对象的信息
- 反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化
- 对象序列化流: ObjectOutputStream
- 将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象
- 构造方法
方法名 说明
ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream
- 序列化对象的方法
方法名 说明
void writeObject(Object obj) 将指定的对象写入ObjectOutputStream
- 示例代码
学生类
public class Student implements Serializable {
private String name;
private int age;
......
}
测试类
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
//ObjectOutputStream(OutputStream out):创建一个写入指定的OutputStream的ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
//创建对象
Student s = new Student("佟丽娅",30);
//void writeObject(Object obj):将指定的对象写入ObjectOutputStream
oos.writeObject(s);
//释放资源
oos.close();
}
}
- 注意事项
- 一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
- Serializable是一个标记接口,实现该接口,不需要重写任何方法
3.2对象反序列化流【应用】
- 对象反序列化流: ObjectInputStream
- ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
- 构造方法
方法名 说明
ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream
- 反序列化对象的方法
方法名 说明
Object readObject() 从ObjectInputStream读取一个对象
- 示例代码
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
//Object readObject():从ObjectInputStream读取一个对象
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
}
}
3.3serialVersionUID&transient【应用】
- serialVersionUID
- 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
- 会出问题,会抛出InvalidClassException异常
- 如果出问题了,如何解决呢?
- 重新序列化
- 给对象所属的类加一个serialVersionUID
- private static final long serialVersionUID = 42L;
- transient
- 如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
- 给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
- 示例代码
学生类
public class Student implements Serializable {
private static final long serialVersionUID = 42L;
private String name;
// private int age;
private transient int age;
......
}
测试类
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// write();
read();
}
//反序列化
private static void read() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
}
//序列化
private static void write() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("myOtherStream\\oos.txt"));
Student s = new Student("佟丽娅", 30);
oos.writeObject(s);
oos.close();
}
}
5.Properties集合(混眼熟)
5.1Properties作为Map集合的使用【应用】
- Properties介绍
- 是一个Map体系的集合类
- Properties可以保存到流中或从流中加载
- 属性列表中的每个键及其对应的值都是一个字符串
5.2Properties作为Map集合的特有方法【应用】
- 特有方法
方法名 说明
Object setProperty(String key, String value) 设置集合的键和值,都是String类型,底层调用 Hashtable方法 put
String getProperty(String key) 使用此属性列表中指定的键搜索属性
Set<String> stringPropertyNames() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
- 示例代码
public class PropertiesDemo02 {
public static void main(String[] args) {
//创建集合对象
Properties prop = new Properties();
//Object setProperty(String key, String value):设置集合的键和值,都是String类型
prop.setProperty("itheima001", "佟丽娅");
prop.setProperty("itheima002", "赵丽颖");
prop.setProperty("itheima003", "刘诗诗");
//String getProperty(String key):使用此属性列表中指定的键搜索属性
// System.out.println(prop.getProperty("itheima001"));
// System.out.println(prop.getProperty("itheima0011"));
// System.out.println(prop);
//Set<String> stringPropertyNames():从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串
Set<String> names = prop.stringPropertyNames();
for (String key : names) {
// System.out.println(key);
String value = prop.getProperty(key);
System.out.println(key + "," + value);
}
}
}
5.3Properties和IO流相结合的方法【应用】
- 和IO流结合的方法
方法名 说明
void load(Reader reader) 从输入字符流读取属性列表(键和元素对)
void store(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流
- 示例代码
public class PropertiesDemo03 {
public static void main(String[] args) throws IOException {
//把集合中的数据保存到文件
// myStore();
//把文件中的数据加载到集合
myLoad();
}
private static void myLoad() throws IOException {
Properties prop = new Properties();
//void load(Reader reader):
FileReader fr = new FileReader("myOtherStream\\fw.txt");
prop.load(fr);
fr.close();
System.out.println(prop);
}
private static void myStore() throws IOException {
Properties prop = new Properties();
prop.setProperty("itheima001","佟丽娅");
prop.setProperty("itheima002","赵丽颖");
prop.setProperty("itheima003","刘诗诗");
//void store(Writer writer, String comments):
FileWriter fw = new FileWriter("myOtherStream\\fw.txt");
prop.store(fw,null);
fw.close();
}
}
File类
1File类概述和构造方法【应用】
- File类介绍
- 它是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也可以是不存在的.将来是要通过具体的操作把这个路径的内容转换为具体存在的
- File类的构造方法
方法名 说明
File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例
File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例
- 示例代码
public class FileDemo01 {
public static void main(String[] args) {
//File(String pathname): 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
File f1 = new File("E:\\itcast\\java.txt");
System.out.println(f1);
//File(String parent, String child): 从父路径名字符串和子路径名字符串创建新的 File实例
File f2 = new File("E:\\itcast","java.txt");
System.out.println(f2);
//File(File parent, String child): 从父抽象路径名和子路径名字符串创建新的 File实例
File f3 = new File("E:\\itcast");
File f4 = new File(f3,"java.txt");
System.out.println(f4);
}
}
2绝对路径和相对路径【理解】
- 绝对路径是一个完整的路径,从盘符开始
- 相对路径是一个简化的路径,相对当前项目下的路径
3File类创建功能【应用】
- 方法分类
方法名 说明
public boolean createNewFile() 当具有该名称的文件不存在时,创建一个由该抽象路径名命名的新空文件
public boolean mkdir() 创建由此抽象路径名命名的目录
public boolean mkdirs() 创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录
4File类删除功能【应用】
只能删除文件、空文件夹
- 方法分类
方法名 说明
public boolean delete() 删除由此抽象路径名表示的文件或目录
2.5File类判断和获取功能【应用】
- 判断功能
方法名 说明
public boolean isDirectory() 测试此抽象路径名表示的File是否为目录
public boolean isFile() 测试此抽象路径名表示的File是否为文件
public boolean exists() 测试此抽象路径名表示的File是否存在
- 获取功能
方法名 说明
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串
public String getName() 返回由此抽象路径名表示的文件或目录的名称
public File[] listFiles() 返回此抽象路径名表示的目录中的文件和目录的File对象数组
getName()
如果调用者是文件,获取文件名和后缀名
如果调用者是文件夹,获取文件夹的名字 学到了! 学到了 学到了! 学到了
页:
[1]