一.IO流概述以及其分类:
二.文件专属:
2.1 java.io.FileInputStream(掌握)
*引入一:
/*
* java.io.FileInputStream:
1.文件字节输入流,万能的,任何类型的文件都可以采用这个流来读
2.字节的方式,完成输入的操作,完成度的操作(硬盘 ----> 内存)
*/
public class FileInputStreamTest01 {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
try {
//创建输入流对象,从硬盘往内存中读
fileInputStream =new FileInputStream("D:\\IOTest\\temp.TXT");
//开始读,因为文件中有 abcdef 这六个字符,我们就读七次试试
int readDate = fileInputStream.read();
System.out.println(readDate);//97
readDate = fileInputStream.read();
System.out.println(readDate);//98
readDate = fileInputStream.read();
System.out.println(readDate);//99
readDate = fileInputStream.read();
System.out.println(readDate);//100
readDate = fileInputStream.read();
System.out.println(readDate);//101
readDate = fileInputStream.read();
System.out.println(readDate);//102
//什么也没有,就返回-1
readDate = fileInputStream.read();
System.out.println(readDate);//-1
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
//关闭流的前提是流不等于空,流是null没必要关闭,避免空指针异常
if (fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 引入二
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
对第一个程序进行改进,循环方式多个字节
分析这个程序的缺点:
一次读取一个字节byte,这样内存和硬盘交互太频繁了,基本上时间/资源都耗费在交互上面了
希望一次读取
*/
public class FileInputStreamTest02 {
public static void main(String[] args) {
//创建字节输入流
FileInputStream fileInputStream =null;
try {
fileInputStream =new FileInputStream("D:\\IOTest\\temp.TXT");
//循环读
/*while(true){
int readDate = fileInputStream.read();
if (readDate == -1){
break;
}
System.out.println(readDate);
}*/
//改进循环
int readDate = 0;
while((readDate = fileInputStream.read()) != -1){
System.out.println(readDate);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 引入三
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* int read(byte[] b)
一次最多读取b.length个字节
*减少硬盘和内存的交互,提高程序的执行效率
* 往byte数组里面读
*/
public class FileInputStreamTest03 {
public static void main(String[] args) {
FileInputStream fileInputStream =null;
try {
fileInputStream = new FileInputStream("D:\\IOTest\\temp.TXT");
//开始读,使用byte数组
//一次读四个字节
byte[] bytes = new byte[4];
//返回值是读取到的字节数,并非读到的字节
int readCount = fileInputStream.read(bytes);
System.out.println(readCount);//4
//返回独处的字节
//将字节数组全部转成字符串
//System.out.println(new String(bytes));//abcd
//读多少转多少
//起始位置 长度
System.out.println(new String(bytes,0,readCount));//abcd
//继续读
readCount = fileInputStream.read(bytes);
//这表示只读了两个
System.out.println(readCount);//2
//将字节数组全部转成字符串
//System.out.println(new String(bytes));//efcd
System.out.println(new String(bytes,0,readCount));//ef
//继续读
readCount = fileInputStream.read(bytes);
//一个都没读到,返回 -1
System.out.println(readCount);//-1
//将字节数组全部转成字符串
// System.out.println(new String(bytes));//efcd
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if (fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 最终版
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
//最终版
public class FileInputStreamTest04 {
public static void main(String[] args) {
FileInputStream fileInputStream =null;
try {
//文件里面就 abc efg hi
fileInputStream = new FileInputStream("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\tempfile");
//准备数组
byte[] bytes = new byte[4];
int readCount = 0;
//循环读
while ((readCount =fileInputStream.read(bytes)) != -1){
System.out.print(new String(bytes,0,readCount));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- InputStream的两种常用方法
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/*
* FileInputStream类其他的常用方法
* int available() : 返回流当中剩余的没有读到的字节数量
long skip(long n) :跳过几个字节不读
*/
public class FileInputStreamTest05 {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
try {
//创建输入流
fileInputStream = new FileInputStream("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\tempfile");
/*
//int available() : 返回流当中剩余的没有读到的字节数量
System.out.println(fileInputStream.available());//10
//读一个字节
System.out.println(fileInputStream.read());//97
//再返回一次还有多少没读
System.out.println(fileInputStream.available());//9
*/
//int available() 有什么用?
//不需要循环了
//可以一次读完所有字节
/*byte[] bytes = new byte[fileInputStream.available()];
int readCount = fileInputStream.read(bytes);
System.out.println(new String(bytes,0,readCount));//abc efg hi*/
//long skip(long n) :跳过几个字节不读
//跳过四个
fileInputStream.skip(4); //abc和空格 efg空格 hi
System.out.println(fileInputStream.read());//101 是e
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.2 java.io.FileOutputStream(掌握)
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 文件字节输入流,负责写
* 从内存到硬盘
*/
public class FileOutputStreamTest01 {
public static void main(String[] args) {
FileOutputStream fileOutputStream =null;
try {
//如果文件不存在会新建
//这种构造方式会将原文件清空再重新写出
//fileOutputStream =new FileOutputStream("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\temp");
//以追加的方式在文件末写入,不会清空原文件
fileOutputStream = new FileOutputStream("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\temp",true);
//输出流文件,最后一定要刷新
fileOutputStream.flush();
//开始写
//将byte数组全部写出
byte[] bytes = {97,98,99,100};
fileOutputStream.write(bytes);
//这样可以在后面再加 ab
//将byte数组一部分写出
fileOutputStream.write(bytes,0,2);
//以字符串的形式写
String string = "钢铁侠,美国队长,雷神";
//将String类型变成byte数组
bytes = string.getBytes();
//写入
fileOutputStream.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fileOutputStream != null){
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.3 使用FileInputStream和FileOutputStream完成文件的拷贝
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 使用FileInputStream和FileOutputStream完成文件的拷贝
* 拷贝的过程应该是一遍读,一边写
* 使用以上的字节流拷贝文件的时候,文件类型随意,万能的,什么样的文件都能拷
* */
public class Copy01 {
public static void main(String[] args) {
FileInputStream fileInputStream =null;
FileOutputStream fileOutputStream =null;
try {
fileInputStream = new FileInputStream("C:\\Users\\A556U\\Desktop\\Java核心技术 卷2 高级特性 原书第10版.pdf");
fileOutputStream =new FileOutputStream("D:\\Java核心技术 卷2 高级特性 原书第10版.pdf");
int readCont = 0;
byte[] bytes = new byte[1024*1024];//一次最多拷1M
//最主要:一边读一边写
while((readCont = fileInputStream.read(bytes)) != -1){
//fileOutputStream.write(bytes);这样最后一部分可能有重复的
fileOutputStream.write(bytes,0,readCont);
}
//有输出流最后要刷新
fileOutputStream.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//分开关闭,否则一个出错会影响另一个关闭
if (fileInputStream != null){
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fileOutputStream != null){
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.4 java.io.FileReader
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/*
* FileReader:
* 文件字符输入流,只能读取普通文本
* 读取文本文件的时候,比较方便,快捷
* */
public class FileReaderTest {
public static void main(String[] args) {
FileReader fileReader =null;
try {
//创建一个文件字符输入流
fileReader = new FileReader("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\temp");
//创建一个char数组
/*
char[] chars = new char[4];//一次读取四个字符
int readCount = 0;
while((readCount = fileReader.read(chars)) != -1){
System.out.println(new String(chars,0,readCount));
}
*/
//或者这样读
//创建一个char数组
char[] chars = new char[30];//一次读完
fileReader.read(chars);
for(char c : chars){
System.out.println(c);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if (fileReader != null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.5 java.io.FileWriter
import java.io.FileWriter;
import java.io.IOException;
/*
*FileWrite:
* 文件字符输出流
* 只能输出普通文本
*/
public class FileWriterTest {
public static void main(String[] args) {
FileWriter fileWriter =null;
try {
//创建文件字符输出对象
fileWriter = new FileWriter("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\temp",true);
//创建char数组
char[] chars = {'钢','铁','侠','雷','神','美','国','队','长'};
//全部写入
fileWriter.write(chars);
//部分写入
fileWriter.write(chars,0,3);
//直接写入字符串
fileWriter.write("钢铁侠好帅");
//换行
fileWriter.write("\n");
//继续写
fileWriter.write("雷神也好帅");
//输出流最后一定要刷新!!!
fileWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fileWriter != null){
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2.6 使用FileReader FileWriter 进行拷贝
//使用FileReader FileWriter 进行拷贝,只能拷贝“普通文本”文件
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Copy02 {
public static void main(String[] args) {
FileReader fileReader =null;
FileWriter fileWriter =null;
try {
fileReader = new FileReader("C:\\Users\\A556U\\Desktop\\java笔记\\day19课堂笔记.txt");
fileWriter = new FileWriter("D:\\day19课堂笔记.txt");
int readCount = 0;
char[] chars =new char[1024 * 1024];//一次读1M
while((readCount = fileReader.read(chars)) != -1){
fileWriter.write(chars,0,readCount);
}
//刷新!!!
fileWriter.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fileReader != null){
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fileWriter != null){
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
三.转换流:(将字节流转换成字符流)
3.1 java.io.InputStreamReader
import java.io.*;
//BufferedReader 的构造方法只能传字符流,不能传字节流
//那么我们可以把字节流变成字符流
public class BufferedReaderTest02 {
public static void main(String[] args) {
BufferedReader bufferedReader =null;
try {
/*//创建一个字节流
FileInputStream fileInputStream = new FileInputStream("D:\\day25课堂笔记.txt");
//通过 转化流 转成 字符流
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
//创建带缓冲区的字符输入流
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);*/
//合并
bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\day25课堂笔记.txt")));
//读
String s =null;
while ((s = bufferedReader.readLine()) != null){
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.2 java.io.OutputStreamWriter
这个是将字节输出流转化成字符输出流,与上面的类似
四.缓冲流专属:
4.1 java.io.BufferedReader
/*
* BufferedReader:
* 带有缓冲区的字符输入流
* 使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲
*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderTest01 {
public static void main(String[] args) {
BufferedReader bufferedReader = null;
try {
//BufferedReader的构造方法需要流
//当一个流的构造方法中需要流的时候,被传进来的流叫做:节点流
//外部负责包装这个流,叫做:包装流,或者叫 处理流
FileReader fileReader = new FileReader("D:\\day25课堂笔记.txt");
//这里 bufferedReader 是包装流 FileReader是节点流
bufferedReader = new BufferedReader(fileReader);
/*String firstLine = bufferedReader.readLine();
System.out.println(firstLine);*/
//循环读
String s = null;
while((s = bufferedReader.readLine()) != null){
System.out.println(s);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭流
//只要关闭包装流,节点流会自动关闭
if (bufferedReader != null){
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.2 java.io.BufferedWriter
/*
* BufferedReader:
* 带有缓冲区的字符输入流
* 使用这个流的时候不需要自定义char数组,或者说不需要自定义byte数组。自带缓冲
*/
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterTest01 {
public static void main(String[] args) {
BufferedWriter bufferedWriter = null;
try {
bufferedWriter = new BufferedWriter(new FileWriter("D:\\day25课堂笔记.txt",true));
//写
bufferedWriter.write("钢铁侠,蜘蛛侠");
//换行
bufferedWriter.write("\n");
bufferedWriter.write("美队,雷神");
//输出流要刷新
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bufferedWriter != null){
try {
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.3 java.io.BufferedInputStream
4.4 java.io.BufferedOutputStream
这两个与上面的类似,只不过这两个是字节流,就不在这赘述了。
五.标准输出流:
5.1 java.io.PrintWriter
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
/*
* java.io.PrintStream:标准的字节输出流,默认输出到控制台
*/
public class PrintStreamTest {
public static void main(String[] args) {
//合并
System.out.println("Hello World");
//分开
PrintStream ps = System.out;
ps.println("Hello 钢铁侠");
ps.println("Hello 美国队长");
ps.println("Hello 雷神");
ps.println("Hello 蜘蛛侠");
//标准输出流不需要手动close()关闭
//可以改变标准输出流的输出方向吗?
//可以
//标准输出流不再指向控制台,指向log文件
try {
//修改输出方向,将输出文件修改到“log”文件
PrintStream printStream =new PrintStream(new FileOutputStream("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\blog"));
//再输出
printStream.println("Hello World");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
5.2 利用标准输出流编写博客工具类
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
//日志工具类
public class Logger {
public static void logger(String message){
try {
PrintStream printStream = new PrintStream(new FileOutputStream("C:\\Users\\A556U\\JavaSE曹鹏\\chapter23 IO流\\src\\caopeng\\javase\\test\\blog",true));
//改变输出方向
System.setOut(printStream);
//获取系统当前时间
Date date =new Date(System.currentTimeMillis());
SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yy-MM-dd HH:mm:ss:SSS");
String strTime = simpleDateFormat.format(date);
printStream.println(strTime + " " +message);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
public class LoggerTest {
public static void main(String[] args) {
Logger.logger("我好厉害");
Logger.logger("今天把IO流笔记弄好");
}
}
六.对象专属流:
6.1 java.io.ObjectOutputStream(掌握)
import java.io.Serializable;
public class Student implements Serializable {
private int no;
private String name;
public Student() {
}
public Student(int no, String name) {
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamTest {
public static void main(String[] args) {
ObjectOutputStream objectOutputStream = null;
try {
//序列化
objectOutputStream =new ObjectOutputStream(new FileOutputStream("Student1"));
//创建java对象
Student student1 =new Student(123,"小明");
//序列化对象
//java.io.NotSerializableException: caopeng.javase.test.Student
//如果Student不实现 Serializable 这个接口,就不能序列化
objectOutputStream.writeObject(student1);
//刷新
objectOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (objectOutputStream != null){
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
6.1 java.io.ObjectInputStream(掌握)
{
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (objectInputStream != null){
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
七.File类:
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* File:
* 1.File类和四大IO流家族,没什么关系,所以file类不能完成文件的读和写
* 2.file类的对象代表什么?
* 文件和目录路径的抽象表达形式
* D:\JAVA 是一个file对象
* D:\JAVA\bin\server\classes.jsa 也是一个file对象
* 一个file对象有可能对应的是目录,也可能是文件
* file只是一个路径的抽象表达形式
* 3.需要掌握file类中的常用方法
* */
public class FileTest01 {
public static void main(String[] args) {
//创建一个file对象
File file1 =new File("D:\\FileTest01");
//判断file对象是否存在
System.out.println(file1.exists());//false
File file2 =new File("D:\\JAVA");
System.out.println(file2.exists());//true
if (!file1.exists()){
try {
//如果不存在就创建一个文件
file1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
File file3=new File("D:\\FileTest02");
if ( !file3.exists()){
//以目录的形式新建
file3.mkdir();
}
//创建多重目录
File file4 =new File("D:/a/b/c/d");
if (!file4.exists()){
file4.mkdirs();
}
File file5 =new File("D:\\JAVA\\bin\\server\\classes.jsa");
//获取父文件的路径
String parentPath = file5.getParent();
System.out.println(parentPath);//D:\JAVA\bin\server
//获取父文件
File parentFile = file5.getParentFile();
System.out.println(parentFile);//D:\JAVA\bin\server
//获取绝对路径
File file6 =new File("tempfile");
String s = file6.getAbsolutePath();
System.out.println(s);
//C:\Users\A556U\IdeaProjects\chapter19数组\tempfile
//获取文件名
String fileName = file6.getName();
System.out.println(fileName);//tempfile
File file7 =new File("C:\\Users\\A556U\\Desktop\\Java核心技术 卷2 高级特性 原书第10版.pdf");
//判断是否是一个目录
System.out.println(file7.isDirectory());//false
//判断是否是一个文件
System.out.println(file7.isFile());//true
//获取文件的大小
System.out.println(file7.length());//205203249 //195 MB (205,203,249 字节)
//获取文件最后一次修改时间
Long time = file7.lastModified();这个毫秒是从1970到修改时间的总毫秒
System.out.println(time);//1573394084000
Date date =new Date(time);
SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
String strTime = simpleDateFormat.format(date);
System.out.println(strTime);//2019-11-10 21:54:44:000
//file[] listFiles()
//获取当前目录下的子文件
File[] file8 = file2.listFiles();
//遍历
for (File file : file8){
System.out.println(file.getName() + " 在 " + file.getAbsolutePath());
}
}
}