IO流

IO流

IO流:输入(Input)输出(Output)流

输入输出是相对于内存来讲的

IO流用来处理设备之间的数据传输

Java对数据的操作是通过流的方式

Java用于操作流的类都在IO包中

流按流向分为两种:输入流,输出流

一、File类

File文件和目录路径名的抽象表示形式。

即,Java中把文件或者目录(文件夹)都封装成File对象。

也就是说如果我们要去操作硬盘上的文件,或者文件夹只要找到File这个类即可。

构造方法:

File(File parent, String child)
从父抽象路径名和子路径名字符串创建新的 File实例。
File(String pathname)
通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
File(String parent, String child)
从父路径名字符串和子路径名字符串创建新的 File实例。
File(URI uri)
通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。

注意点:

1、文件路径

绝对路径:从盘符开始到文件的路径

相对路径:从某个参照路径开始到指定文件所经过的路径

2、文件分隔符:

Windows:\

Unix(Linux、Mac OS)?

File.sperator:获取当前系统的文件分隔符

常用方法
获取功能

File getAbsoluteFile() 返回此抽象路径名的绝对形式。

public String getPath() 获取路径(用什么方式创建的对象,就返回什么方式的路径(绝对路径/相对路径))

public String getName() 获取文件/文件夹的名称

public String getParent() 返回所在文件夹路径(根据创建对象时是否为绝对路径/相对路径)

long lastModified()
返回此抽象路径名表示的文件上次修改的时间。 (时间戳 毫秒)
long length()
返回由此抽象路径名表示的文件的大小。

创建与删除

public boolean createNewFile() throws IOException 创建文件

在创建文件时,如果文件所在的文件夹不存在,则报错系统找不到指定的路径.创建文件时,必须确保文件夹已经存在

public boolean mkdir() 使用mkdir方法创建文件夹时,必须保证其所在文件夹已经存在,否则创建失败(不会报错)

public boolean mkdirs() 一次性创建多级目录

public boolean delete() 删除文件夹不能为非空(有东西),否则删除失败

判断

public boolean exists() 文件或者文件夹是否存在

public boolean isDirectory() 判断文件对象是否为文件夹

public boolean isFile() 判断文件对象是否为文件

获取目录下的结构(必须是目录对象调用)

public File[] listFiles()  获取调用方法文件夹下的所有file对象(文件或文件夹)

String[] list() 返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录。

public static void main(String[] args){
    //File对象创建方式一:
    File file1 = new File("hello.txt");//相对路径:相当于当前目录
    File file2 = new File("D:\\a.txt");//绝对路径
    System.out.println(file1);//hello.txt
  System.out.println(file1.getAbsoluteFile());//E:\workspace\20190917\hello.txt
}
IO流基本划分:

1、按照操作的数据类型:字节流、字符流

2、按照流的流向:输入流、输出流

3、按照流的角色:节点流、处理流

流操作规律

(1)第一步:先明确源和目的源

​ 源:字节(InputStream) 字符(Reader)

​ 目的:字节(OutputStream) 字符(Writer)

(2)明确是不是纯文本:

​ 是:用字符流

​ 不是:用字节流

(3)明确流体系后,通过设备来明确设备来明确具体使用哪个流对象

IO体系:

抽象对象 节点流(文件流) 缓冲流(属于处理流的一种)

InputStream(字节) FileInputStream BufferedInputStream

OutputStream FileOutputStream BufferedOutputStream

Reader(字符) FileReader BufferedReader

Writer FileWriter BufferedWriter

1、字符流
1.1字符文件流

1.1.1字符文件输入流FileReader

//常用方法:int read()、int read(char[] cbuf)
//需求:hello.txt需要读取文件中字符内容

//1.创建文件对象
File file = new File("hello.txt");

//2.创建字符(文件)输入流对象
FileReader reader = new FileReader(file);

//3.读取数据
//方式一:一次读取一个字符
int read = reader.read();//read() 读取单个字符 ASCII
while(read!=-1){
    System.out.print((char)read);
    read = reader.read();
}
//方式一 优化
int read;
while((read = reader.read()!=-1)){
    System.out.print((char)read);
}

//方式二
//定义读取字符的数组
char[] cbuf = new char[5];
int len;
while((len = reader.read(cbuf))!=-1){
    for(int i = 0;i<len;i++){
    	System.out.print(chuf[i]);
    }
}

4.关闭资源(流对象不会自动关闭,也不会被垃圾回收机制回收)
reader.close();

1.1.2字符文件输出流FileWriter

注意:

对于文本文件(.txt .java .c .cpp)可以使用字符流(字节流(可传不可看))传输

对于非文本文件(.png .avi .jpg .word)必须使用字节流传输

//常用方法:write()、write(String str)、write(char[] cbuf,int offset,int len)、write(char[] cbuf)
//将内存中数据写入磁盘中
//helloigeekhome
//1.创建文件对象(指定文件位置用于写入)
//注意点:
//1、如果文件不存在,那么会自动创建文件,并将内容写入到文件中,不会报错
//2、默认情况下,fw.write()会覆盖文件内容
File file = new File("hello.txt");
//2.创建输出流对象(字符)FileWriter
FileWriter fw = new FileWriter(file);
//3.写入
fw.write("helloigeekhome");
//4.关闭资源
fw.close();

1.1.3字符流文件拷贝

public class ReaderAndWriterDemo {
	public static void main(String[] args) {
		FileReader fr = null;
		FileWriter fw = null;
		try {
			fr = new FileReader("D:\\a.txt");
			fw = new FileWriter("D:\\b.txt");
			int len = -1;
			char[] cbuf = new char[1024];
			while((len = fr.read(cbuf))!=-1) {
				fw.write(cbuf, 0, len);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(fw!=null) {
				try {
					fw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(fr!=null) {
				try {
					fr.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}	
	}
}
2、字节流
2.1文件字节流

2.1.1字节输入流

FileInputStream

2.1.2字节输出流

FileOutputStream

2.1.3字节流文件拷贝

public class FileInputStreamDemo01 {
	public static void main(String[] args) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("D:\\a.txt");
			fos = new FileOutputStream("D:\\aa.txt");
			byte[] b = new byte[1024];
			int len = -1;
			while ((len = fis.read(b)) != -1) {
				fos.write(b, 0, len);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (fis != null) {
			try {
				fis.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
3、缓冲流

作用:提高数据的读取与写入的效率

提高效率的原因(以字节缓冲流为例):因为缓冲流内置了缓冲区,缓冲区默认的是8129长度的字节\字符数组,当每次write操作中,如果缓冲区满了,会将自动将数据刷到文件中,当调用close()方法时,也会自动将数据刷新到内存中

3.1使用字符缓冲流拷贝文件
public class BufferedReaderAndWriter {
	public static void main(String[] args) {
		BufferedReader br = null;
		BufferedWriter bw = null;
		try {
			FileReader fr = new FileReader("E:\\a.txt");
			FileWriter fw = new FileWriter("E:\\b.txt");
			br = new BufferedReader(fr);
			bw = new BufferedWriter(fw);
			String line = null;
			while((line = br.readLine())!=null) {
				bw.write(line);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(bw!=null) {
				try {
					bw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(br!=null) {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
3.2使用字节缓冲流拷贝文件
public class BufferedInputStreamAndOutputStream {
	public static void main(String[] args) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("D:\\a.txt");
			BufferedInputStream bis = new BufferedInputStream(fis);
			fos = new FileOutputStream("E:\\a.txt");
			BufferedOutputStream bos = new BufferedOutputStream(fos);
			byte[] buf = new byte[1024];
			int len = -1;
			while((len = bis.read(buf))!=-1) {
				fos.write(buf, 0, len);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(fos!=null) {
				try {
					fos.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(fis!=null) {
				try {
					fis.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
4、转换流

InputStreamReader:可以完成字节输入流转换为字符输入流

OutputStreamWriter:可以完成字节输出流转换为字符输出流

使用转换流主要是因为字符输入流有readLine()方法,可以一次读取一行

4.1使用转换流拷贝文件
public class Transform {
	public static void main(String[] args) {
		BufferedReader br = null;
		BufferedWriter bw = null;
		try {
			FileInputStream fis = new FileInputStream("D:\\a.txt");
			FileOutputStream fos = new FileOutputStream("D:\\c.txt");
			InputStreamReader isr = new InputStreamReader(fis);
			OutputStreamWriter osr = new OutputStreamWriter(fos);
			br = new BufferedReader(isr);
			bw = new BufferedWriter(osr);
			String line = null;
			while((line = br.readLine())!=null) {
				osr.write(line);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(bw!=null) {
				try {
					bw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(br!=null) {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
}
5、其他流
5.1对象序列化与反序列化【掌握】

将自定义对象、String进行持久化(保存到文件中)=>序列化

将文件中的内容读取转换为自定义对象 =>反序列化

用于向流中写入对象的操作流ObjectOutputStream称为序列化流

用于从文件中读取对象的操作流ObjectInputStream称为反序列化流

特点:用于操作对象。可以将对象写入到文件中,也可以从文件中读取对象

自定义对象如果需要实现序列化操作,必须实现Serializable接口,否则抛出java.io.NotSerializableException

序列化机制就是允许将内存中的Java对象转换为与平台无关的二进制数据,可以将这些二进制数据永久的存储在磁盘中,或者通过网络传输到其他网络节点,只要其他程序获取到了这些二进制数据,就可以把数据再次转换为对象

5.1.1序列化操作 内存=>文件

public class ObjectOutputStreamDemo {
	public static void main(String[] args) throws FileNotFoundException, IOException {
		//1、创建写出文件对象
		File dest = new File("D:\\aaa.txt");//序列化操作的持久化文件可以是任意数据类型,不需要查看
		//2、创建序列化对象
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(dest));
		//3、将对象写入输入流
		oos.writeObject("我有一个梦想");
		
		//自定义对象如果需要实现序列化操作,必须实现Serializable接口,否则抛出java.io.NotSerializableException
		oos.writeObject(new User("1","Jack"));
	}
}
class User implements Serializable{
	private String id;
	private String name;
	public User() {}
	public User(String id,String name) {
		this.id = id;
		this.name = name;
	}
}

5.1.2反序列化 文件=>内存(对象)

public class ObjectInputStreamDemo {
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		//1、创建读取文件对象
		File dest = new File("D:\\aaa.txt"); 
		//2、创建读取流
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(dest));
		//3、读取文件,获取对象
		//readObject顺序要按照writeObject的顺序
		String str = (String)ois.readObject();
		User user = (User)ois.readObject();
		System.out.println(str);
		System.out.println(user);
		ois.close();
	}
}

注意点:

1、如果一个对象需要支持序列化与反序列化,那么该对象所属的类必须实现Serializable接口(类对应的对象具有了序列化与反序列化的能力)

2、需要实现序列化的类需要提供个serialVersionUID(如果没有提供,那么JVM会自动提供。每次修改类,该值都会发生变化)public static final long serialVersionUID = 1321554L;

3、如果一个类需要支持序列化与反序列化操作,那么这个类的所有属性也需要支持序列化与反序列化

4、被static与transient关键字修饰的属性无法被序列化

5.2标准的输入流、标准输出流【了解】

System.in 标准输入流(键盘)

System.out 标准输出流 (控制台)

5.3打印流【了解】

打印流只有输出流

PrintStream 字节打印流,调用println方法时自动刷新

PrintWriter 字符打印流,指定自动刷新开关后,调用println方法时自动刷新,无需手动调用flush()方法

tln(user);
ois.close();
}
}


**注意点:** 

1、如果一个对象需要支持序列化与反序列化,那么该对象所属的类必须实现Serializable接口(类对应的对象具有了序列化与反序列化的能力)

2、需要实现序列化的类需要提供个serialVersionUID(如果没有提供,那么JVM会自动提供。每次修改类,该值都会发生变化)public static final long serialVersionUID = 1321554L;

3、如果一个类需要支持序列化与反序列化操作,那么这个类的所有属性也需要支持序列化与反序列化

4、被static与transient关键字修饰的属性无法被序列化



###### 5.2标准的输入流、标准输出流【了解】

System.in  标准输入流(键盘)

System.out  标准输出流  (控制台)



###### 5.3打印流【了解】

打印流只有输出流

PrintStream  字节打印流,调用println方法时自动刷新

PrintWriter  字符打印流,指定自动刷新开关后,调用println方法时自动刷新,无需手动调用flush()方法



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值