IO五大类+一个接口
File
InputStream,OutputStream(字节输入输出流)
Reader,Writer(字符输入输出流)
Serializable序列化接口
后四个为抽象类,要通过向上转型,最麻烦的就是他们四个有很多种子类
File常用方法(File可以是文件也可以是目录)
File(String pathname),File(File parent,String child)构造方法
createNewFile()创建新文件
mkdirs()创建目录(多级目录)
exists()文件/目录是否存在
delete()删除文件/目录
getParentFile()获取当前路径的父路径
length()取得文件大小,以字节为单位返回
isFile()是否是文件
isDirectory()是否是目录
lastModified()获取文件/目录最后一次修改时间
list()获取指定目录的全部内容(String[]形式)
listFiles()获取指定目录下的全部内容的路径(File[]形式)
getName()获取文件/目录名称
getPath()获取路径的String表示
File.separator路径分隔符常量(因为历史原因,常量没有全部大写,windows分隔符为\\,第一个\为转义字符,Linux为/)
InputStream基本用法
read()
可以单个字节读取,也可以读取全部字节到字节数组,也可以读取部分字节到字节数组
示例代码:一次性读取
File file=new File("C:\\Users\\Administrator\\Desktop\\test116.txt");
InputStream inputStream=new FileInputStream(file);
byte[] b=new byte[1024];
int len=inputStream.read(b);
inputStream.close();
System.out.println(len);
System.out.println(new String(b,0,len));
示例代码:循环进行单字节读取
File file1=new File("C:\\Users\\Administrator\\Desktop\\aaa\\b.txt");
InputStream inputStream1=new FileInputStream(file1);
byte[] b1=new byte[50];
int index=0;
int data=0;
while((data=inputStream1.read())!=-1){
b1[index++]= (byte) data;
}
inputStream1.close();
System.out.println(index);
System.out.println(new String(b1,0,index));
P.s.读取utf-8编码格式的txt文件时开头多出了3字节,是utf-8编码格式的标记标识EF BB BF,也叫BOM(Byte Order Mark)
有时应用程序会做处理,有时需要我们手动处理
OutputStream基本用法
write()
可以输出全部字节,可以单个字节循环输出,也可以输出部分字节
示例代码:
File file2=new File("C:\\Users\\Administrator\\Desktop\\aaa\\b.txt");
OutputStream outputStream=new FileOutputStream(file2);
String s="这个是字节输出流的子类文件流";
byte[] b=s.getBytes();
outputStream.write(b);
outputStream.close();
这里多次执行是覆盖数据,可以用FileOutputStream(file,boolean append)来进行数据追加
Writer基本用法
write()输出字符
append()追加字符
示例代码:
File file3=new File("C:\\Users\\Administrator\\Desktop\\aaa\\c.txt");
Writer writer=new FileWriter(file3);
String s="这个是字符输出流的测试aaaaaa";
writer.write(s);
writer.close();
//追加数据
Writer writer2=new FileWriter(file3,true);
writer2.append(s);
writer2.close();
Reader基本用法
read()读取字符
skip()跳过n个字符
示例代码:
File file2=new File("C:\\Users\\Administrator\\Desktop\\aaa\\b.txt");
Reader reader=new FileReader(file2);
reader.skip(1);
char[] b2=new char[50];
int len=reader.read(b2);
reader.close();
System.out.println(new String(b2,0,len));
字符流字节流最大区别:
字节流数据直接与终端文件交互
字符流数据→缓冲区→终端文件,若不close或者flush则数据一直留着缓冲区
转换流
OutputStreamWriter
字节输出流转字符输出流
InputStreamReader
字节输入流转字符输入流
(只有字节转字符,没有字符转字节)
文件流
FileInputStream / FileOutputStream / FileReader / FileWrite
文件复制2种方案:
一次性读取一次性输出
(大文件可能会导致崩溃)
一点点读取一点点输出
(速度会慢一点)(可以调节字节数组的大小控制快慢,字节数组太小要多次读取写入速度会慢,字节数组太大可能导致崩溃)
示例代码:
long startTime=System.currentTimeMillis();
File file=new File("C:\\Users\\Administrator\\Desktop\\test116.txt");
InputStream inputStream=new FileInputStream(file);
File file2=new File("C:\\Users\\Administrator\\Desktop\\test116(copy).txt");
OutputStream outputStream=new FileOutputStream(file2);
int len=0;
byte[] b=new byte[1024];
while ((len=inputStream.read(b))!=-1){
outputStream.write(b,0,len);
}
inputStream.close();
outputStream.close();
long endTime=System.currentTimeMillis();
System.out.println(endTime-startTime);
这里每次读取写入1024字节也就是1KB,复制的文件13.4M,复制花费时间52毫秒
内存流
在进行IO操作的时候我们不希望磁盘上产生文件,而是利用内存作为临时文件中进行读写操作时可以使用内存流
ByteArrayInputStream内存字节输入流
ByteArrayOutputStream内存字节输出流
CharArrayReader内存字符输入流
CharArrayWriter内存字符输出流
实际应用:
1.对文件的内容进行修改而不保存,直接输出修改结果
2.两个文件的合并读取,不保存读取结果直接输出结果
打印流:
PrintStream字节打印流
PrintWriter字符打印流
(为了方便String,Int,Double...等基本数据类型的输出)
示例代码:
File file3=new File("C:\\Users\\Administrator\\Desktop\\aaa\\d.txt");
OutputStream outputStream=new FileOutputStream(file3);
PrintStream printStream=new PrintStream(outputStream);
printStream.print("这是一行文字");
printStream.println(111);
printStream.println(66.66);
printStream.println('帅');
Java1.5开始支持PrintStream使用格式化输出,类似C语言那样 printf("姓名:%s,年龄:%d,成绩:%5.2f",name,age,grade)
System对IO的支持
PrintStream out显示器信息输出
PrintStream err显示器err信息输出,直接用out也可以
InputStream in键盘数据输入
示例代码:
System.err.printIn(e)
System.out.printIn("hello world")
InputStream input=System.in
字符缓冲流
有字节/字符 输入/输出缓冲流
这里介绍BufferedReader字符输入缓冲流
主要方法:BufferedReader(Reader in),readLine()
将数据一行行读取到缓冲区(运行在内存),然后再从缓冲区获取数据
扫描流Scanner(并非在io包中,属于工具类)
Scanner(InputStream in)构造方法
hasNext()是否有数据
next()取出数据,String类型
hasNextXxx()是否有Xxx类型的数据
nextXxx()取出数据,Xxx类型
useDelimiter(String pattern)设置读取的分隔符
示例代码:
File file3=new File("C:\\Users\\Administrator\\Desktop\\aaa\\d.txt");
InputStream inputStream=new FileInputStream(file3);
Scanner scanner=new Scanner(inputStream);
// scanner.useDelimiter("一");
while(scanner.hasNext()){
System.out.println(scanner.next());
}
对象序列化
对象保存在内存中,它们的生命周期不会超出JVM进程
想要在JVM进程结束后把对象保存下来,或者不同JVM进程间传递对象就需要将对象序列化
Serializable序列化接口
只有实现该接口的类的对象才能被序列化
class Book implements Serializable
ObjectOutputStream序列化操作类
ObjectOutputStream(OutputStream out)构造方法
writeObject(Object obj)序列化对象
ObjectInputStream序列化反操作类
ObjectInputStream(InputStream in)构造方法
readObject()反序列化对象
transient关键字用于声明属性不可序列化