JAVA核心技术(2)IO
目录
1、File
2、文件过滤器+遍历文件夹
3、相对路径和绝对路径
4、IO流
4.1、字节流
4.1.1、OutputStream 抽象类
4.1.2、InputputStream 抽象类
4.2、字符流
4.2.1、Writer抽象类
4.2.2、Reader抽象类
4.3、转换流。将字节流装饰为字符流:使用装饰者设计模式
4.4、字符输出打印流、缓冲读取流
4.5、输出错误日志
5、Properties
6、序列化与反序列化
6.1、序列化中忽略不想序列化的属性
6.1.1、transient关键字
6.1.2、static关键字
6.1.3、默认方法实现序列化
6.1.4、Externalizable接口,实现序列化
6.1.5、Serializable接口与Externalizable
7、try-with-resources
1、File
构造器 |
描述 |
File(File parent, String child) |
从父抽象路径名和子路径名字符串创建新的 File实例。 |
File(String pathname) |
通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 |
File(String parent, String child) |
从父路径名字符串和子路径名字符串创建新的 File实例。 |
常用方法:
变量和类型 |
方法 |
描述 |
String |
getAbsolutePath() |
返回此抽象路径名的绝对路径名字符串。 |
File |
getAbsoluteFile() |
返回此抽象路径名的绝对形式。 |
String |
getParent() |
返回此抽象路径名父项的路径名字符串,如果此路径名未指定父目录,则返回 null 。 |
File |
getParentFile() |
返回此抽象路径名父项的抽象路径名,如果此路径名未指定父目录,则返回 null 。 |
String |
getPath() |
将此抽象路径名转换为路径名字符串。 |
long |
length() |
返回此抽象路径名表示的文件的长度。单位Byte。1024B = 1KB |
boolean |
exists() |
测试此抽象路径名表示的文件或目录是否存在。 |
boolean |
isDirectory() |
测试此抽象路径名表示的文件是否为目录。 |
boolean |
isFile() |
测试此抽象路径名表示的文件是否为普通文件。 |
String[] |
list() |
返回一个字符串数组,用于命名此抽象路径名表示的目录中的文件和目录。 |
File[] |
listFiles() |
返回一个抽象路径名数组,表示此抽象路径名表示的目录中的文件。 |
boolean |
mkdir() |
创建此抽象路径名指定的目录,父目录不存在就创建不出来 |
boolean |
mkdirs() |
创建此抽象路径名指定的目录,父目录不存在会把父目录创建 |
boolean |
renameTo(File newFile) |
剪切并重命名 |
boolean |
delete() |
删除此抽象路径名表示的文件或目录。删除文件要谨慎,删掉不会在回收站 |
成员属性:不同系统路径用的符号会不同,用这个替代不会出错
变量和类型 |
字段 |
描述 |
static String |
pathSeparator |
与系统相关的路径分隔符,为方便起见,表示为字符串。 |
static char |
pathSeparatorChar |
与系统相关的路径分隔符。 |
static String |
separator |
系统相关的默认名称分隔符,为方便起见,表示为字符串。 |
static char |
separatorChar |
系统相关的默认名称分隔符。 |
2、文件过滤器+遍历文件夹
package com.syp.file.test;import java.io.File;
import java.io.FileFilter;/*** @author suyiping* @create 2021-06-23 19:33*/
public class Test {public static void main(String[] args) {File file = new File("E:/");showFiles(file);}static void showFiles(File file) {File[] files = file.listFiles(new FileFilter() {@Overridepublic boolean accept(File f) {if ((f.getName().endsWith(".exe") && f.length() > 10 * 1024 * 1024) || f.isDirectory())return true;return false;}});if (files == null || files.length == 0) {return;}for (File f : files) {//如果是文件夹,就继续往下层找if (f.isDirectory()) {showFiles(f);} else {System.out.println(f.getAbsoluteFile() + "\tSize:" + f.length() / (1024 * 1024) + "MB");}}}}
3、相对路径和绝对路径
绝对路径:从盘符开始,是一个完整的路径 例如: E://a/1.txt
相对路径:相对于项目目录的路径
4、IO流
Input:输入,输入(读)到JAVA程序
Ouput:输出,输出(写)到别的地方,例如写到系统中
分类:
按照流的方向:输入流、输出流
按照流动的数据类型:字符流(文字)、字节流(其他)
字符流和字节流:
字节流操作的基本单元为字节byte;字符流操作的基本单元为Unicode码元(char)。
字节流默认不使用缓冲区;字符流使用缓冲区。
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元;字符流通常处理文本数据,它支持写入及读取Unicode码元。
用字节流读取文字,可能会出现某一个中文,占3个字节,被多次读取,就识别不出来的情况,所以要用转换流,把字节转换成字符
用字符流操作文字,需要使用flush方法刷新缓存。close方法中,也会先执行flush
顶级父类:
输出流 |
输入流 |
|
字节流 |
InputStream |
OuputStream |
字符流 |
Reader |
Writer |
4.1、字节流
一切皆字节:计算机中的任何数据,都是以二进制的形式存储的,8个bit就是一个字节。在数据传输时,也都是以二进制存储的。
后续学习的任何流,在传输时,底层都是二进制(包括字符流)
4.1.1、OutputStream 抽象类
变量和类型 |
方法 |
描述 |
void |
close() |
关闭此输出流并释放与此流关联的所有系统资源。关闭要尽可能早,且用完一定要关闭 |
void |
flush() |
刷新此输出流并强制写出任何缓冲的输出字节。 |
static OutputStream |
nullOutputStream() |
返回一个新的 OutputStream ,它丢弃所有字节。 |
void |
write(byte[] b) |
将 b.length字节从指定的字节数组写入此输出流。 |
void |
write(byte[] b, int off, int len) |
将从off下标开始,写出len个字节 |
abstract void |
write(int b) |
将指定的字节写入此输出流。 |
FileOutputStream 实现类,通过这个流,可以向指定的文件,输出内容
构造器 |
描述 |
FileOutputStream(File file) |
创建文件输出流以写入由指定的 File对象表示的文件。 |
FileOutputStream(FileDescriptor fdObj) |
创建要写入指定文件描述符的文件输出流,该文件描述符表示与文件系统中实际文件的现有连接。 |
FileOutputStream(File file, boolean append) |
创建文件输出流以写入由指定的 File对象表示的文件。append为true,就是接着原来的往后写,为false就是把文件内容清空,重新写 |
FileOutputStream(String name) |
创建文件输出流以写入具有指定名称的文件。 |
FileOutputStream(String name, boolean append) |
创建文件输出流以写入具有指定名称的文件。 |
FileOutputStream使用构造方法指定一个File或文件路径构造一个流,如果文件不存在,会自动创建文件,除非权限不够
一个流创建之后,不管有没有append,都可以write多次,write的位置会接着上一次write结束的位置,直到关闭
4.1.2、InputputStream 抽象类
变量和类型 |
方法 |
描述 |
int |
available() |
返回可以从此输入流中无阻塞地读取(或跳过)的字节数的估计值,可以是0,或者在检测到流结束时为0。 |
void |
close() |
关闭此输入流并释放与该流关联的所有系统资源。 |
void |
mark(int readlimit) |
标记此输入流中的当前位置。 |
boolean |
markSupported() |
测试此输入流是否支持 mark和 reset方法。 |
static InputStream |
nullInputStream() |
返回一个不读取任何字节的新 InputStream 。 |
abstract int |
read() |
从输入流中读取下1个数据字节。 值字节返回int ,范围为0至255 。 如果由于到达流末尾而没有可用字节,则返回值-1 。 此方法将阻塞,直到输入数据可用,检测到流的末尾或抛出异常。 |
int |
read(byte[] b) |
从输入流中读取一些字节数并将它们赋值到缓冲区数组 b 。返回实际读取的字节数。如果b的长度为零,则不读取任何字节,并返回0 ; 否则,尝试读取至少一个字节。 如果由于流位于文件末尾而没有可用字节,则返回值-1 ; 否则,至少读取一个字节并存储到b 。 |
int |
read(byte[] b, int off, int len) |
从输入流 len最多 len字节的数据读入一个字节数组。 |
byte[] |
readAllBytes() |
从输入流中读取所有剩余字节。 |
int |
readNBytes(byte[] b, int off, int len) |
从输入流中读取请求的字节数到给定的字节数组中。 |
byte[] |
readNBytes(int len) |
从输入流中读取指定的字节数。 |
void |
reset() |
将此流重新定位到上次在此输入流上调用 mark方法时的位置。 |
long |
skip(long n) |
跳过并丢弃此输入流中的 n字节数据。 |
long |
transferTo(OutputStream out) |
从该输入流中读取所有字节,并按读取顺序将字节写入给定的输出流。 |
FileInputStream 实现类
构造器 |
描述 |
FileInputStream(File file) |
通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的 File对象 file命名。 |
FileInputStream(FileDescriptor fdObj) |
使用文件描述符 fdObj创建 FileInputStream ,该文件描述符表示与文件系统中实际文件的现有连接。 |
FileInputStream(String name) |
通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的路径名 name命名。 |
FileInputStream如果没有读取到文件,不会自动创建
一个流在read之后,如果没有close,可以接着read,read的位置接着上一次read的末尾
尽量使用byte[]来读取字节,而不是单读取一个byte多次,read次数越少越好。这样速度才会快
public static void main(String[] args) throws IOException {FileOutputStream fos = new FileOutputStream("E:/1.txt");byte[] bytes = "1234567890".getBytes();fos.write(bytes);fos.close();FileInputStream fis = new FileInputStream("E:/1.txt");byte[] byte1 = new byte[2];int len = 0;while (len != -1) {System.out.println(new String(byte1,0,len));len = fis.read(byte1);}fis.close();System.out.println(Arrays.toString(byte1));
}
4.2、字符流
4.2.1、Writer抽象类
变量和类型 |
方法 |
描述 |
Writer |
append(char c) |
将指定的字符追加到此writer。 |
Writer |
append(CharSequence csq) |
将指定的字符序列追加到此writer。 |
Writer |
append(CharSequence csq, int start, int end) |
将指定字符序列的子序列追加到此writer。 |
abstract void |
close() |
关闭流,先冲洗它。 |
abstract void |
flush() |
刷新流。 |
static Writer |
nullWriter() |
返回一个新的 Writer ,它丢弃所有字符。 |
void |
write(char[] cbuf) |
写一个字符数组。 |
abstract void |
write(char[] cbuf, int off, int len) |
写一个字符数组的一部分。 |
void |
write(int c) |
写一个字符。 |
void |
write(String str) |
写一个字符串。 |
void |
write(String str, int off, int len) |
写一个字符串的一部分。 |
FileWriter 实现类
构造器 |
描述 |
FileWriter(File file) |
给 File写一个 FileWriter ,使用平台的 default charset |
FileWriter(FileDescriptor fd) |
构造一个 FileWriter给出的文件描述符,使用该平台的 default charset 。 |
FileWriter(File file, boolean append) |
在给出要写入的 FileWriter下构造 File ,并使用平台的 default charset构造一个布尔值,指示是否附加写入的数据。 |
FileWriter(File file, Charset charset) |
构造一个FileWriter给予File编写和charset 。 |
FileWriter(File file, Charset charset, boolean append) |
构造FileWriter给出File写入, charset和一个布尔值,指示是否附加写入的数据。 |
FileWriter(String fileName) |
构造一个 FileWriter给出文件名,使用平台的 default charset |
FileWriter(String fileName, boolean append) |
使用平台的 default charset构造一个 FileWriter给定一个文件名和一个布尔值,指示是否附加写入的数据。 |
FileWriter(String fileName, Charset charset) |
构造一个FileWriter给出文件名和charset 。 |
FileWriter(String fileName, Charset charset, boolean append) |
构造一个FileWriter给定一个文件名, charset和一个布尔值,指示是否附加写入的数据。 |
4.2.2、Reader抽象类
变量和类型 |
方法 |
描述 |
abstract void |
close() |
关闭流并释放与其关联的所有系统资源。 |
void |
mark(int readAheadLimit) |
标记流中的当前位置。 |
boolean |
markSupported() |
判断此流是否支持mark()操作。 |
static Reader |
nullReader() |
返回不读取任何字符的新 Reader 。 |
int |
read() |
读一个字符。 |
int |
read(char[] cbuf) |
将字符读入数组。 |
abstract int |
read(char[] cbuf, int off, int len) |
将字符读入数组的一部分。 |
int |
read(CharBuffer target) |
尝试将字符读入指定的字符缓冲区。 |
boolean |
ready() |
判断此流是否可以读取。 |
void |
reset() |
重置流。 |
long |
skip(long n) |
跳过字符。 |
long |
transferTo(Writer out) |
读取此阅读器中的所有字符,并按照读取的顺序将字符写入给定的编写器。 |
FileReader 实现类
构造器 |
描述 |
FileReader(File file) |
使用平台 FileReader ,在 File读取时创建一个新的 FileReader 。 |
FileReader(FileDescriptor fd) |
使用平台 default charset创建一个新的 FileReader ,给定 FileDescriptor进行读取。 |
FileReader(File file, Charset charset) |
创建一个新的FileReader ,给出File读取和charset 。 |
FileReader(String fileName) |
使用平台 default charset创建一个新的 FileReader ,给定要读取的文件的 名称 。 |
FileReader(String fileName, Charset charset) |
给定要读取的文件的名称和FileReader ,创建一个新的FileReader 。 |
public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("E:/b.txt");fw.write("龘龘龘龘龖龖龘惡惡辶辶");fw.append("11111").append("22222").append("33333");fw.flush();fw.close();FileReader fr = new FileReader("E:/b.txt");char[] chars = new char[2];int lenth = 0;while (lenth != -1) {System.out.println(new String(chars, 0, lenth));lenth = fr.read(chars);}
}
BufferedReader和FileReader区别
BufferedReader(FileReader("filename"))将FileReader包装后,再使用read(char[] chbf)读取,可以将文件内容装入缓存。而FileReader则会频繁使用底层IO,造成阻塞其他需要访问IO的操作,所以读取文件BufferedReader比FileReader更高效。
BufferedReader提供了readLine方法。可以读取一整行为一个String
4.3、转换流。将字节流装饰为字符流:使用装饰者设计模式
InputStreamReader
构造器 |
描述 |
InputStreamReader(InputStream in) |
创建一个使用默认字符集的InputStreamReader。 |
InputStreamReader(InputStream in, String charsetName) |
创建一个使用指定charset的InputStreamReader。 |
InputStreamReader(InputStream in, Charset cs) |
创建一个使用给定charset的InputStreamReader。 |
InputStreamReader(InputStream in, CharsetDecoder dec) |
创建一个使用给定charset解码器的InputStreamReader。 |
OutputStreamReader
public static void main(String[] args) throws IOException {FileInputStream fis = new FileInputStream("E:/b.txt");InputStreamReader isr = new InputStreamReader(fis, "utf-8");while (true) {int word = isr.read();if (word == -1) {break;}System.out.println((char)word);}FileOutputStream fos = new FileOutputStream("E:/b.txt");OutputStreamWriter osw = new OutputStreamWriter(fos);osw.write("床前明月光");osw.flush();osw.close();}
4.4、字符输出打印流、缓冲读取流
PrintStream
PrintWriter 也可以转换字节流进行输出
public static void main(String[] args) throws FileNotFoundException {PrintStream ps = new PrintStream("E:/c2.txt");ps.println("11111");ps.println("22222");ps.println("33333");ps.close();PrintWriter pw = new PrintWriter("E:/c1.txt");pw.println("55555");pw.println("55555");pw.println("55555");pw.flush();pw.close();FileOutputStream fos = new FileOutputStream("E:/b.txt");PrintWriter pw1 = new PrintWriter(fos);pw1.println("bbbbbbbbb");pw1.flush();pw1.close();
}
BufferedReader
可以将FileReader转为BufferedReader,进行读取行
读取行readLine读完时,会返回null
public static void main(String[] args) throws IOException {FileReader fr = new FileReader("E:/c2.txt");BufferedReader br = new BufferedReader(fr);while (true) {String str = br.readLine();if (str == null) {break;}System.out.println(str);}
}
4.5、输出错误日志
public static void main(String[] args) throws FileNotFoundException {String s = null;try {s.toString();} catch (Exception e) {PrintWriter pw = new PrintWriter("E:/bugs.txt");e.printStackTrace(pw);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");pw.println("报错时间:" + sdf.format(new Date()));pw.close();}
}
5、Properties
本质上是一个HashTable,操作与HashMap一致
变量和类型 |
方法 |
描述 |
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) |
已过时。现在用store 如果在保存属性列表时发生I / O错误,则此方法不会抛出IOException。 |
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文档。 |
void |
storeToXML(OutputStream os, String comment, Charset charset) |
使用指定的编码发出表示此表中包含的所有属性的XML文档。 |
Set<String> |
stringPropertyNames() |
从此属性列表返回一组不可修改的键,其中键及其对应的值是字符串,如果尚未从主属性列表中找到相同名称的键,则包括默认属性列表中的不同键。 |
public static void main(String[] args) throws IOException {Properties properties = new Properties();properties.put("userName", "11111");properties.put("password", "666666");FileWriter fw = new FileWriter("E:/userInfo.properties");properties.store(fw,"啊啊啊啊龘龘");fw.flush();fw.close();Properties p2 = new Properties();FileReader r = new FileReader("E:/userInfo.properties");p2.load(r);System.out.println(p2.getProperty("userName"));System.out.println(p2.get("username"));System.out.println(p2.get("password"));r.close();
}
6、序列化与反序列化
序列化:把对象存到文件
反序列化:把文件转为对象
要序列化的类型,需要实现Serializable接口。要序列化的类型中的属性如果是一个类,也要实现Serializable接口
存入的如果是集合,拿出来也要用对应的集合装
public class Test9 {public static void main(String[] args) throws IOException, ClassNotFoundException {//写入数据/*LinkedList<Book> list = new LinkedList<>();Book book1 = new Book("第一本书", "语文书");Book book2 = new Book("第二本书", "数学书");Book book3 = new Book("第三本书", "英语书");list.add(book1);list.add(book2);list.add(book3);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/books.txt"));oos.writeObject(list);oos.close();*///读取数据ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/books.txt"));LinkedList<Book> bookList = (LinkedList<Book>) ois.readObject();System.out.println(bookList.toString());}static class Book implements Serializable {private String name;private String info;@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", info='" + info + '\'' +'}';}public Book() {}public Book(String name, String info) {this.name = name;this.info = info;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}}
}
6.1、序列化中忽略不想序列化的属性
6.1.1、transient关键字
在实现序列化接口的类的属性前 加上 transient关键字 priavate transient String name。该属性就会在序列化的时候被忽略
6.1.2、static关键字
用static修饰的字段,也不会被序列化,但是这个值因为是static的,会在JVM中和这个字段所属的类进行绑定,如果这个属性被赋值过,且JVM没有关闭,创建类时,一样会读取到这个属性,且是唯一的。
public class Test9 {public static void main(String[] args) throws IOException, ClassNotFoundException {//写入数据LinkedList<Book> list = new LinkedList<>();Book book1 = new Book("第一本书", "语文书");Book book2 = new Book("第二本书", "数学书");Book book3 = new Book("第三本书", "英语书");list.add(book1);list.add(book2);list.add(book3);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/books.txt"));oos.writeObject(list);oos.close();//读取数据ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/books.txt"));Collection<Object> bookList = Collections.singleton(ois.readObject());System.out.println(bookList.toString());}static class Book implements Serializable {private transient String name;private static String info;@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", info='" + info + '\'' +'}';}public Book() {}public Book(String name, String info) {this.name = name;this.info = info;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}}
}
输出结果:
[[Book{name='null', info='英语书'}, Book{name='null', info='英语书'}, Book{name='null', info='英语书'}]]
6.1.3、默认方法实现序列化
private void writeObject(ObjectOutputStream out){}
private void readObject(ObjectInputStream in){}
在要序列化的类中,手动添加 写入序列化方法或者读取序列化方法,也能达到把想序列化的属性,进行序列化的效果,不受transient的影响
该方法必须是 private void的
但是static的原则,如上,依然存在
package com.syp.file.test;import java.io.*;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;/*** @author suyiping* @create 2021-06-24 21:25*/
public class Test9 {public static void main(String[] args) throws IOException, ClassNotFoundException {//写入数据LinkedList<Book> list = new LinkedList<>();Book book1 = new Book("第一本书", "语文书", 10);Book book2 = new Book("第二本书", "数学书", 11);Book book3 = new Book("第三本书", "英语书", 12);list.add(book1);list.add(book2);list.add(book3);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/books.txt"));oos.writeObject(list);oos.close();//读取数据ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/books.txt"));Collection<Object> bookList = Collections.singleton(ois.readObject());System.out.println(bookList.toString());}static class Book implements Serializable {private transient String name;private static String info;private Integer age;@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", info='" + info + '\'' +", age=" + age +'}';}private void writeObject(ObjectOutputStream out) throws IOException {out.writeObject(name);
// out.writeObject(age);}private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {name = (String) in.readObject();
// age = (Integer) in.readObject();}public Book() {}public Book(String name, String info, int age) {this.name = name;this.info = info;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
}
输出结果
[[Book{name='第一本书', info='英语书', age=null}, Book{name='第二本书', info='英语书', age=null}, Book{name='第三本书', info='英语书', age=null}]]
6.1.4、Externalizable接口,实现序列化
与6.1.3中使用方法类似,作为了解就行,不常用
package com.syp.file.test;import java.io.*;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;/*** @author suyiping* @create 2021-06-24 21:25*/
public class Test9 {public static void main(String[] args) throws IOException, ClassNotFoundException {//写入数据LinkedList<Book> list = new LinkedList<>();Book book1 = new Book("第一本书", "语文书", 10);Book book2 = new Book("第二本书", "数学书", 11);Book book3 = new Book("第三本书", "英语书", 12);list.add(book1);list.add(book2);list.add(book3);ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:/books.txt"));oos.writeObject(list);oos.close();//读取数据ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:/books.txt"));Collection<Object> bookList = Collections.singleton(ois.readObject());System.out.println(bookList.toString());}static class Book implements Externalizable {private transient String name;private static String info;private Integer age;@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", info='" + info + '\'' +", age=" + age +'}';}public Book() {}public Book(String name, String info, int age) {this.name = name;this.info = info;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(name);}@Overridepublic void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {name = (String) in.readObject();}}
}
6.1.5、Serializable接口与Externalizable
区别 |
Serializable |
Externalizable |
实现复杂度 |
实现简单 |
实现复杂 |
执行效率 |
所有对象统一保存,速度相对慢 |
部分保存,速度相对快 |
保存信息 |
全部保存,保存时空间相对使用较大 |
部分保存,空间使用相对较小 |
使用频率 |
高 |
低,面试有可能问到 |
7、try-with-resources
JDK1.7之前
public static void main(String[] args) {FileReader fr =null;try {fr = new FileReader("E:/1.txt");int c = fr.read();if (c != -1) {System.out.println((char) c);}} catch (IOException e) {e.printStackTrace();}finally {try {fr.close();} catch (IOException e) {e.printStackTrace();}}
}
JDK1.7时 在try()中可以声明一个类,该类必须是实现了Closeable接口的,结束try后,会自动close
public static void main(String[] args) throws FileNotFoundException {try (FileReader fr = new FileReader("E:/1.txt")) {int c = fr.read();if (c != -1) {System.out.println((char) c);}} catch (IOException e) {e.printStackTrace();}
}
JDK9 用分号隔开。可以放入多个类
public static void main(String[] args) throws FileNotFoundException {FileReader fr = new FileReader("E:/1.txt");FileInputStream fis = new FileInputStream("E:/1.txt");try (fr; PrintWriter pw =new PrintWriter("E:/1.txt");fis) {int c = fr.read();if (c != -1) {System.out.println((char) c);}} catch (IOException e) {e.printStackTrace();}
}
JAVA核心技术(2)IO相关推荐
- 你必须掌握的 21 个 Java 核心技术!
经过这么多年的Java开发,以及结合平时面试Java开发者的一些经验,我觉得对于J2SE方面主要就是要掌握以下的一些内容. 1. JVM相关 对于刚刚接触Java的人来说,JVM相关的知识不一定需要理 ...
- Java 基本功之(三)Java 核心技术
转载自https://github.com/Snailclimb/JavaGuide/blob/master/docs/java/basis/Java%E5%9F%BA%E7%A1%80%E7%9F% ...
- Java核心技术笔记 语言基础
<Java核心技术 卷Ⅰ> 第3章 Java 的基本程序设计结构 一些规则 类命名:CamelCase 驼峰命名法,以及必须是字母开头,后面跟字母和数字的任意组合: 源代码文件名:必须与公 ...
- Java核心技术笔记 异常、断言和日志
<Java核心技术 卷Ⅰ> 第7章 异常.断言和日志 处理错误 捕获异常 使用异常机制的技巧 记录日志 处理错误 如果由于出现错误而是的某些操作没有完成,程序应该: 返回到一种安全状态,并 ...
- 你必须掌握的 21 个 Java 核心技术
转载自 你必须掌握的 21 个 Java 核心技术 写这篇文章的目的是想总结一下自己这么多年来使用java的一些心得体会,希望可以给大家一些经验,能让大家更好学习和使用Java. 这次介绍的主要内容 ...
- Java 核心技术卷 II(第 8 版) – 读书笔记 – 第 1 章(下)
22.一旦获得了一个 Charset,就可以在 Java 的 Unicode 和指定的编码格式之间进行转化,下面以 GBK 和 Unicode 之间做为例子. 从 Unicode 到 GBK: imp ...
- Java核心技术卷一 -第十二章:多线程
系列文章目录 Java核心技术卷一 -第一章:java"白皮书"的关键术语 Java核心技术卷一 -第三章:数据类型 Java核心技术卷一 -第三章:变量与常量 Java核心技术卷 ...
- 《Java 核心技术 卷1》 笔记 第11章 异常、日志、断言和调试
出现不可预计的问题时,需要进行如下处理: 报告错误 保存操作结果 允许用户退出 本章解决的问题: 验证程序正确性 记录程序错误 调试技巧 11.1 处理异常 程序出现错误时应该: 返回安全状态,能让用 ...
- Java核心技术·卷二·第一章笔记
Java核心技术·卷二·笔记 第一章:Java8的流库 Java8引入的用来以"做什么而非怎么做"的方式的处理集合 1.1 从迭代到流的操作 package com.package ...
- java核心技术卷I 第1-3章 笔记
java核心技术卷I 第1-3章 本书将详细介绍下列内容: ● 面向对象程序设计 ● 反射与代理 ● 接口与内部类 ● 异常处理 ● 泛型程序设计 ● 集合框架 ● 事件监听器模型 ● 使用Swing ...
最新文章
- 计算机基础课程教学创新,【计算机基础论文】大学计算机基础课程教学创新探讨(共5359字)...
- 凤凰式期权matlab代码,美式期权二叉树定价及MATLAB程序.doc
- libssl-dev linux下载,libssl
- java商品名称_Java统计商品信息
- 机器学习-笔试题总结1
- PHP-表单提交(form)
- ajax上传文件判断大小,JavaScript检测上传文件大小的方法
- 安卓游戏 我叫mt 3.5.4.0 3540,data.dat 文件解包记录
- python3GUI--磁力搜索工具(附tk源码)
- 忘记网站后台密码 PHP+mysql+md5 破解
- 【CIPS 2016】(4-5章)语言认知模型、语言表示以及深度学习(研究进展、现状趋势)
- 用java编写球体的体积,编写一个程序,提示用户输入球体的半径并打印其体积...
- 计算机网络之数据链路层原理
- 在Dynamics 365 CRM 中使用Xrm.WebApi实现增,删,改,查(需V9.0或以上)
- 34. 在排序数组中查找元素的第一个和最后一个位置
- Hibernate_9_Person和IdCard实例_一对一关系:基于主键
- 大型高并发高负载网站的系统架构[转载]
- 动环监控串口,动环监控系统接口
- 集合,ArrayList的运用、 Add()、AddRange()、Clear()、 IndexOf()等
- c++中的 for_each 函数