输入/输出流
I/O(input/output)流
输入流(input stream or input object)的指向称作“源”
输出流(output stream or output object)的指向称作“目的地”
程序的“源”和“目的地”可以是文件、键盘、鼠标、内存或显示器窗口

4个abstract class
InputStream(字节输入流)
OutputStream(字节输出流)
Reader(字符输入流)
Writer(字符输出流)

文件

构造方法

1
2
File(String filename);
File(String directoryPath, String filename);

属性

1
2
3
4
5
6
7
8
9
10
11
public String getName()//获取文件的名字
public boolean canRead()//判断文件是否可读
public boolean canWrite()//判断文件是否可被写入
public boolean exits()//判断文件是否存在
public long length()//获取文件的长度(单位是字节)
public String getAbsolutePath()//获取文件的绝对路径
public String getParent()//获取文件的父目录
public boolean isFile()//判断文件是否是一个正常的文件
public boolean isDirectory()//判断文件是否是一个目录
public boolean isHidden()//判断文件是否是隐藏文件
public long lastModified()//获取文件最后修改的时间

目录

1
2
3
4
5
6
7
//创建目录
public boolean mkdir()
//列出目录中的文件(File对象是一个目录)
public String[] list()//用字符串数组的形式返回目录下的全部文件
public String[] list(FilenameFilter ff)//用字符串数组的形式返回目录下指定类型的全部文件
public File[] listFiles()//用File对象数组的形式返回目录下的全部文件
public File[] listFiles(FilenameFilter ff)//用File对象数组的形式返回目录下指定类型的全部文件

文件的创建与删除

File file = new File("c:\\myletter","letter.txt");
public boolean delete()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.io.*;
class FileAccept implements FilenameFilter
{
String str = null;
FileAccept(String s) //文件类型(后缀)
{
str = "." + s;
}
public boolean accept(File dir, String name) //文件目录,名字
{
return name.endsWith(str);
}
}
public class demo
{
public static void main(String args[])
{
//File dir = new File("C:/ch8"); // 推荐使用
File dir = new File("D:\\Java\\code\\course\\src\\...");
// File dir = new File("C/ch8"); // illegal
// File dir = new File("C:\ch8"); // illegal

FileAccept fileAccept = new FileAccept("java"); //类型
File[] files = dir.listFiles(fileAccept); //用File对象数组的形式返回目录下的全部文件
for(int i=0; i<files.length; i++)
{
System.out.println(files[i].getName() + ": " + files[i].length());
}

boolean flag = false;
if(files.length>0) //如果至少有一个文件
{
flag = files[0].delete();
}
if(flag)
{
System.out.println(files[0].getName() + " has been deleted.");
}
}
}

运行可执行文件

使用Runtime类声明一个对象
使用静态方法getRuntime()创建这个对象
Runtime rt = Runtime.getRuntime();
rt可以调用exec(String command)方法打开本地机器的可执行文件/执行一个操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.io.*; 
public class Example9_2
{
public static void main(String args[])
{
try
{
Runtime rt = Runtime.getRuntime(); //创建对象
File file = new File("C:\\windows", "Notepad.exe");
rt.exec(file.getAbsolutePath()); //打开本地机器的可执行文件/执行操作
}
catch(Exception e){}
}
}

使用Scanner解析文件

先把文件的内容全部读入内存后进行解析,处理速度快 ——> 以空间(内存)换时间
使用Scanner类和正则表达式来解析文件 ——> 以时间换空间(内存)

使用默认分隔符标记解析文件

text:
TV cost 876 dollar, Computer cost 2398 dollar. The milk cost 98 dollar. The apple cost 198 dollar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.*;
import java.util.*;

public class demo2 {

public static void main(String args[])
{
File file = new File("C:\\Users\\26555\\Desktop\\JAVA\\cost.txt");
Scanner scanner = null;
int sum=0;
try{
scanner = new Scanner(file);
//对于数字型的单词,可用nextInt()或nextDouble()方法来代替next()方法
//scanner将空格作为分隔标记、调用next()方法依次返回file中的单词,
//如果file最后一个单词已被next()方法返回,scanner调用hasNext()将返回false,否则返回true。
while(scanner.hasNext()){
try{
int price = scanner.nextInt();
sum = sum + price;
System.out.println(price);
}
//如果单词不是数字型单词,调用nextInt()或nextDouble()方法将发生InputMismatchException异常。在处理异常时可以调用next()方法返回该非数字化单词
catch(InputMismatchException exp){
String t = scanner.next();
}
}
System.out.println("Total Cost:"+sum+" dollar");
}
catch(Exception exp){ System.out.println(exp); }
}
}

使用正则表达式作为分隔标记解析文件

text
市话费:176.89元,长途费:187.98元,网络费:928.66元

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.io.*;
import java.util.*;

public class demo3 {
public static void main(String args[]){
File file = new File("C:\\Users\\26555\\Desktop\\JAVA\\communicate.txt");
Scanner scanner = null;
double sum = 0;
try {
double fare=0;
scanner = new Scanner(file);
scanner.useDelimiter("[^0123456789.]+"); //正则表达式(匹配所有非数字字符串
while(scanner.hasNextDouble()){
fare = scanner.nextDouble();
sum = sum+fare;
System.out.println(fare);
}
System.out.println("Total: " + sum);
}
catch(Exception exp){
System.out.println(exp);
}
}
}

单词记忆训练

文件字符流

FileReader类

1
2
3
4
5
6
7
// 构造方法
FileReader(String name)
FileReader(File file)
// 常用方法
int read()//读取一个字符(即2个字节),返回0~65535之间的一个整数(Unicode字符值),如果未读出字符就返回-1。
int read(char b[ ])//读取b.length个字符到字符数组b中,返回实际读取的字符数目;如果到达文件的末尾,则返回-1。
int read(char b[ ], int off, int len)//读取len个字符并存放到字符数组b中,返回实际读取的字符数目;如果到达文件的末尾,则返回-1。其中,off参数指定read方法在字符数组b中的什么地方存放数据。

FileWriter类

1
2
3
4
5
6
7
8
//构造方法
FileWriter(String name)
FileWriter(File file)
//常用方法
void write(char b[])//将b.length个字符写到输出流
void write(char b[], int off, int len)//从给定字符数组中起始于偏移量off处开始写len个字符到输出流,参数b是存放了数据的字符数组
void write(String str)//把字符串中的全部字符写到输出流
void write(String str, int off, int len)//从字符串str中起始于偏移量off处开始写len个字符到输出流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.*; 
public class Example9_4
{
public static void main(String args[])
{
File file = new File("hello.txt");
char b[] = "深圳大学".toCharArray(); //字符串->字符数组
try
{
FileWriter output = new FileWriter(file); //构造
output.write(b); //字符数组
output.write("脚踏实地!"); //字符串
output.close();
FileReader input = new FileReader(file); //构造
int n=0;
while((n=input.read(b,0,2))!=-1) //最多读2个字符
{
String str = new String(b,0,n); // 转换为字符串
System.out.println(str);
}
input.close();
}
catch(IOException e){
System.out.println(e);
}
}
}

缓冲流

BufferedReader类

1
2
3
4
5
6
7
//构造方法:
BufferedReader(Reader in)

//向BufferedReader传递一个Reader对象(如FileReader对象)-> 创建一个BufferedReader对象
FileReader fr = new FileReader("Student.txt");
BufferedReader input = new BufferedReader(fr);
//input调用readLine()顺序读取文件Student.txt中的一行

BufferedWriter类

1
2
3
4
5
6
7
FileWriter fw = new FileWriter("hello.txt"); 
BufferedWriter output = new BufferedWriter(fw);

//BufferedWritter流调用
//把字符串s或s的一部分写入到目的地
write(String s)
write(String s, int off, int len)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import java.io.*; 
public class Example9_5
{
public static void main(String args[])
{
try
{
FileReader fr = new FileReader("input.txt");
BufferedReader input = new BufferedReader(fr);
FileWriter fw = new FileWriter("output.txt");
BufferedWriter output = new BufferedWriter(fw);
String s=null;
int i=0;
while((s = input.readLine())!=null) //读入
{
i++;
output.write(i + ": " + s); //输出
output.newLine();
}
output.flush();
output.close(); fw.close();
input.close(); fr.close();
}
catch(IOException e){
System.out.println(e);
}
}
}

文件字节流

FileInputStream类

1
2
3
4
5
6
7
8
//构造方法
FileInputStream(String name)
FileInputStream(File file)

//把多个字节读到一个字节数组中
int read(byte b[ ]);
int read(byte b[ ], int off, int len); //off参数指定read()方法把数据存放在字节数组b中的什么地方,len参数指定该方法将要读取的最大字节数。
//上面所示的这两个read()方法都返回实际读取的字节数,如果它们到达输入流的末尾,则返回-1。

FileOutputStream类

1
2
3
4
5
6
7
//构造方法
FileOutputStream(String name)
FileOutputStream(File file)

//输出流通过使用write()方法把数据写入输出流到达目的地
public void write(byte b[]);//写b.length个字节到输出流
public void write(byte b[], int off, int len);//从给定字节数组中起始于偏移量off处开始写len个字节到输出流,参数b是存放了数据的字节数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.io.*; 
public class Example9_3
{
public static void main(String args[])
{
File file = new File("hello.txt");
byte b[] = "深圳大学".getBytes(); //字符数组
try
{
FileOutputStream output = new FileOutputStream(file);
output.write(b); // 字节数组 写b.length个字节到输出流
output.close();
FileInputStream input = new FileInputStream(file);
int n=0;
while( (n=input.read(b,0,3))!=-1 ) // 最多读3个字节
{
String str = new String(b,0,n); // 转换为字符串
System.out.println(str);
}
}
catch(IOException e){
System.out.println(e);
}
}
}

数据流

DataInputStream类和DataOutputStream类
数据输入流 和 数据输出流
构造方法
DataInputStream(InputStream is)
DataOutputStream(OutputStream os)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.io.*; 
public class Example9_8
{
public static void main(String args[])
{
try
{
FileOutputStream fos = new FileOutputStream("jerry.dat");
DataOutputStream output = new DataOutputStream(fos);
output.writeInt(100);
output.writeChars("I am ok");
}
catch(IOException e){}
try
{
FileInputStream fis = new FileInputStream("jerry.dat");
DataInputStream input = new DataInputStream(fis);
System.out.println(input.readInt());
char c;
while((c=input.readChar())!='\0') //'\0'表示空字符
System.out.print(c);
}
catch(IOException e){}
}
}


对象流

ObjectInputStream类和ObjectOutputStream类
对象输入流 和 对象输出流
构造方法
ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.io.*; 
class Goods implements Serializable //Serializable接口 -> 序列化的对象(a serializable object)
{
String name = null;
double unitPrice;
Goods(String name, double unitPrice)
{
this.name=name;
this.unitPrice=unitPrice;
}
public void setUnitPrice(double unitPrice){
this.unitPrice=unitPrice;
}
public double getUnitPrice(){
return unitPrice;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
}
public class Example9_9
{
public static void main(String args[])
{
Goods TV1 = new Goods("HaierTV",3468);
try{
FileOutputStream fileOut = new FileOutputStream("a.txt");
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
objectOut.writeObject(TV1);

FileInputStream fileIn = new FileInputStream("a.txt");
ObjectInputStream objectIn = new ObjectInputStream(fileIn);
Goods TV2 = (Goods)objectIn.readObject();

TV2.setUnitPrice(8888);
TV2.setName("GreatWall");
System.out.printf("\nTv1:%s,%f",TV1.getName(),TV1.getUnitPrice());
System.out.printf("\nTv2:%s,%f",TV2.getName(),TV2.getUnitPrice());
}
catch(Exception event){
System.out.println(event);
}
}
}

序列化和对象克隆

随机读写流

文件锁

数组流

字符串流