目录
一、文件
理解文件
文件简单的可以理解成,在外设硬盘上面保存数据的一种方式
文件一共可以由两部分构成:属性(文件大小,文件名,文件类型等)+内容(就是文件里面放的是什么)
所以我们学 JavaIO ,学什么呢?就学对文件的属性和内容进行操作,而实际写入或者读取的过程,我们称之为IO
二、流
1.数据的流向
设备从输入输出来分,不同的视角表现为不同的输入或输出设备
硬盘角度:
java程序读取本地文件,硬盘做为输出设备
写数据,硬盘输入设备,接收数据.
java程序角度
读取本地文件,硬盘是输入设备
写数据,硬盘是输出设备
一般我们说输入输出设备都是站在Java程序 的角度看来说
2.流的操作只能执行一次
3.Java中IO流的分类
①字节、字符流:
InputStream,OutputStream(字节流),
Writer,Reader(字符流)
②输入,输出:
Input输入;Output输出;
Writer;输出;Reader输出入
③文件:带File的IO类,作为文件操作的IO流
④二进制数组:ByteArray
⑤Java对象:Object
⑥特殊IO流
PrintWriter表示打印输出到某个设备
Scanner表示接收某个设备的输入(接收控制台输入时,从System.in键盘作为输入设备来的)
StringWriter
StringReader (了解)
4.Java中的IO流,是可以包裹其他IO流的
5.流的关闭:IO流的操作完成后一定要释放资源:顺序是根据依赖关系,反向释放
6.PrintWriter操作
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Scanner;
public class PrintWriterTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
new Thread(new Runnable() {
@Override
public void run() {
try {
if(sc.nextInt()==0)
throw new RuntimeException("i==0");
System.out.println();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
StringWriter sw=new StringWriter();
PrintWriter pw=new PrintWriter(sw);
e.printStackTrace(pw);
String stackTrace= sw.toString();
System.out.println(stackTrace);
}
}
}).start();
}
}
三、File操作
1、读操作
字节流转换为字符流需要使用字节字符转换流
InputStreamReader:输入的字节字符转换流OutputStreamWriter:输出的字节字符转换流
(1)按行读取
(2)按字符数组读取
(3)按字节读取
@Test
public void testRead1() throws IOException {
// 字节流转换为字符流,需要使用字节字符转换流
// 转换流可以设置编码:java文件的编码格式、文件编码格式
// InputStreamReader:输入的字节字符转换流,或OutputStreamWriter:输出的字节字符转换流
FileInputStream fis = new FileInputStream(
new File("D:\\javacode\\Javaweb\\io-study\\src\\lesson2/info.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
//字符流的按行读取
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}
//字符流按字符数组读取
char[] chars = new char[1024];
int len ;
while((len = br.read(chars)) != -1){
String str = new String(chars, 0, len);
System.out.println(str);
}
}
@Test
public void testRead2() throws IOException {
FileInputStream fis = new FileInputStream(
new File("D:\\javacode\\Javaweb\\io-study\\src\\lesson2/info.txt"));
//按字节读取
byte[] bytes=new byte[1024];
int len;
while ((len=fis.read(bytes))!=-1){
String str=new String(bytes,0,len);
System.out.println(str);
}
}
2、写操作
使用OutputStreamWrite转换流 及BufferedInputStream缓冲输入流
先将文件内容写入缓冲区使用flush刷新,从缓冲区发送到目的设备
@Test
public void testWrite1() throws IOException {
FileOutputStream fos = new FileOutputStream(
new File("D:\\javacode\\Javaweb\\io-study\\src\\lesson2/info.txt"));
BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
//使用缓冲流,输出的时候,要进行flush刷新缓冲区,否则不会真实输出数据到目的设备
br.write("1:的说法就是打开附件\n");//write写数据到系统内存缓冲区
br.write("2:dskfjdsjf\n");
br.write("3:四道口附近的收费");
br.flush();//缓冲区刷新,发送数据到目的设备
}
3、复制操作
给定一个原文件地址一个目的文件地址,将原文件中的内容写入目的文件中,完成后释放资源
@Test
public void copyFile() throws Exception {
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
//作业:复制本地文件到另一个地方
fis = new FileInputStream(
new File("D:\\javacode\\Javaweb\\io-study\\src\\lesson2/info.txt"));
bis = new BufferedInputStream(fis);
fos = new FileOutputStream(
new File("D:\\javacode\\Javaweb\\io-study\\src\\lesson2/info1.txt"));
bos = new BufferedOutputStream(fos);
byte[] bytes = new byte[1024 * 8];
int len;
while ((len = fis.read(bytes)) != -1) {
bos.write(bytes);
bos.flush();
}
}finally {// IO流的操作完成之后,一定要释放资源,顺序是根据依赖关系B依赖A,反向释放(先释放B)
if(bis != null)
bis.close();
if(fis != null)
fis.close();
if(bos != null)
bos.close();
if(fos != null)
fos.close();
}
}
4、File常用方法
(1)基本文件操作
public boolean exists(): 测试指定路径中文件或者目录是否存在
public boolean isDirectory() :判定一个文件是目录
public boolean isFile(): 判定是否是文件
public boolean delete(): 删除文件
public boolean createNewFile() throwsIOException:创建一个新文件
import java.io.File;
import java.util.Arrays;
public class FileTest {
public static void main(String[] args) {
File file1 = new File("D:\\Workspaces\\java13\\io-study\\res");
File file2 = new File("D:\\Workspaces\\java13\\io-study\\res1");
System.out.println(file1.isDirectory());
System.out.println(Arrays.toString(file1.listFiles()));
System.out.println(file1.getPath());
System.out.println(file2.exists());
file2.mkdirs();
StringBuilder sb = new StringBuilder("计算机").append("软件");
print(sb);
}
// 变量和值(对象)区分开,=号赋值引用指向
// 传入参数、局部变量是在线程执行方法的时候创建,方法执行完就销毁
// 这些信息是以栈帧保存在栈里边,和(线程)执行(方法)相关
public static void print(StringBuilder sb){// StringBuilder sb="计算机软件";
int i = 0;
print(sb);
}
}
(2)目录操作
public boolean mkdir() :创建一个空目录
public boolean mkdirs(): 创建目录
public String getParent(): 取得父路径
public File getParentFile():取得父File对象
(3)文件属性操作
public long length() 取得文件大小(字节)
public long lastModified() 最后一次修改日期
四、序列化和反序列化
1.概念
序列化:把对象转换为字节序列的过程称为对象的序列化。
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
2.什么吗时候需要序列化
(1) 把内存中的对象状态保存到一个文件中或者数据库中时候;
(2)用套接字在网络上传送对象的时候;
3.实现Java对象序列化及反序列化
一个类如果想被序列化,那么需要实现一个Serializable接口。
import java.io.*;
public class SerializableTest {
public static void main(String[] args) throws Exception {
// new SerializableTest().new Person2();
// SerializableTest test = new SerializableTest();
// test.new Person2();
Person person = new SerializableTest.Person();
// 序列化
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("D:\\javacode\\Javaweb\\io-study\\src\\lesson2//person"));
oos.writeObject(person);
// 反序列化
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("D:\\javacode\\Javaweb\\io-study\\src\\lesson2//person"));
Person person1 = (Person) ois.readObject();
System.out.println(person1);
}
private static class Person implements Serializable {
private String name;
private Integer age;
}
// private class Person2{}
}