File类和IO流的字节流(1)

File类和IO流的字节流(1)

一、File类

1.File,是文件和目录路径名的抽象表示

2.File只关注文件本身的信息(文件名、可读、可写),而不能操作文件里面的内容

3.File类 – 表示文件或文件夹,不能对文件里的数据进行操作

4.对文件里的数据进行操作的是:IO流

1.File类的常用方法

import java.io.File;
import java.text.SimpleDateFormat;

public class Test01 {

	public static void main(String[] args) {
		
		//创建File对象
		File file = new File("D:\\图库\\海底世界.jpg");
		
		System.out.println("获取文件名:" + file.getName());
		System.out.println("获取文件大小(字节):" + file.length());
		System.out.println("获取是否可读:" + file.canRead());
		System.out.println("获取是否可写:" + file.canWrite());
		System.out.println("获取是否隐藏:" + file.isHidden());
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy--MM--dd HH--mm--ss");
		String dateTime = sdf.format(file.lastModified());
		System.out.println("获取最后的修改时间:" + dateTime);
	}
}

2.研究绝对路径和相对路径

绝对路径:指定了盘符的具体路径

相对路径:相对于此项目下的路径

import java.io.File;

public class Test02 {

	public static void main(String[] args) {
		//创建File对象
		File file = new File("IO笔记.txt");
		//相对路径:IO笔记.txt
		System.out.println("相对路径:" + file.getPath());
		//绝对路径: F:\2211workspace\MyDay22\IO笔记.txt
		System.out.println("绝对路径: " + file.getAbsolutePath());
	}
}

3.通过程序,判断指定路径的文件是否存在,如果不存在,则创建该文件下面按各种情况来解决该问题

1.目录已存在的情况

import java.io.File;
import java.io.IOException;

public class Test01 {

	public static void main(String[] args) throws IOException {
		
		File file = new File("file01\\gl.txt");
		
		if (!file.exists()) {//判断文件是否存在
			//创建文件
			file.createNewFile();
		}
	}
}

2.有一个层级的目录不存在的情况

import java.io.File;
import java.io.IOException;

public class Test02 {

	public static void main(String[] args) throws IOException {
		
		File file = new File("file\\gl.txt");
		//file01
		File parentFile = file.getParentFile();
		
		if (!parentFile.exists()) {//判断文件夹是否存在
			//创建一层文件夹
			parentFile.mkdir();
		}
		
		if (!file.exists()) {//判断文件是否存在
			//创建文件
			file.createNewFile();
		}
	}
}

3.有多个层级的目录不存在的情况

import java.io.File;
import java.io.IOException;
public class Test03 {

	public static void main(String[] args) throws IOException {
		
		File file = new File("file01\\file02\\file03\\gl.txt");
		//file01\\file02\\file03
		File parentFile = file.getParentFile();
		
		if (!parentFile.exists()) {//判断文件夹是否存在
			//创建多层文件夹
			parentFile.mkdirs();
		}
		
		if (!file.exists()) {//判断文件是否存在
			//创建文件
			file.createNewFile();
		}
	}
}

4.输出指定目录下的所有文件信息(只考虑当前目录,不考虑子目录)

import java.io.File;

public class Test01 {

	public static void main(String[] args) {
		
		File file = new File("F:\\2211workspace");
		
		//解决方案1:
		//获取到该文件夹下所有的文件名
		//String[] list = file.list();
		//for (String str : list) {
		//	System.out.println(str);
		//}
		
		//解决方案2:
		//获取到该文件夹下所有的File对象
		File[] listFiles = file.listFiles();
		for (File f : listFiles) {
			System.out.println(f.getName() + "---" + f.canRead());
		}
	}
}

1.要求只输出文件后缀名为java的文件

import java.io.File;

public class Test02 {

	public static void main(String[] args) {
		
		File file = new File("F:\\2211workspace\\MyDay06");
		
		//解决方案1:
		//获取到该文件夹下所有的文件名
	//	String[] list = file.list();
	//	for (String str : list) {
	//		if (str.endsWith(".class")) {
	//			System.out.println(str);
	//		}
	//	}
		
		//解决方案2:
		//获取到该文件夹下所有的File对象
		File[] listFiles = file.listFiles();
		for (File f : listFiles) {
			String name = f.getName();
			if (f.isFile() && name.endsWith(".java")) {
				System.out.println(name);
			}
		}
	}
}

2.根据API的过滤器来完成该功能

import java.io.File;
import java.io.FilenameFilter;

public class Test03 {

	public static void main(String[] args) {
		
		File file = new File("F:\\2211workspace\\MyDay06");
		
		File[] listFiles = file.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				
				//dir -- new File("C:\\飞秋共享");
				//name -- 遍历的文件名
				
				//创建File对象 -- C:\\飞秋共享\\遍历的文件名
				
				File f = new File(dir, name);
				
				if (f.isFile() &&  name.endsWith(".java")) {
					return true;
				}
				return false;
			}
		});
		
		for (File f : listFiles) {
			System.out.println(f.getName());
		}
	}
}

3.需求继续跟进,列出当前目录及子目录中jpg的文件信息(递归)

import java.io.File;
public class Test04 {

	public static void main(String[] args) {
		
		File file = new File("D:\\图库");
		
		scannerFile(file,".jpg");
	}
	
	public static void scannerFile(File file, String suffix) {

		File[] listFiles = file.listFiles();
		
		for (File f : listFiles) {
			if (f.isDirectory()) {//文件夹
				scannerFile(f, suffix);
			}else if (f.isFile()) {//文件
				String name = f.getName();
				if (name.endsWith(suffix)) {
					System.out.println(name + "--" + f.getAbsolutePath());
				}
			}
		}
		
	}
}


二、IO流

1.理解:

I - in - 输入流
O - out- 输出流
流 - 像水流一样传输数据
注意:站在程序的角度去理解输入输出

应用场景:通过程序处理文件里的内容

2.分流:

​ 按照方向分:输入流、输出流
​ 按照单位分:字节流、字符流
​ 按照功能分:基础流/节点流、处理流
​ 注意:处理流往往包含了基础流,让流的功能更加强大

计算机存储单位:
1024B  = 1Kb
1024kb = 1KB
1024Mb = 1Gb
1024Gb = 1Tb
1024Tb = 1Pb

三、利用文件字节输出流 向文件写入数据

1.文件存在的情况下

import java.io.FileOutputStream;
import java.io.IOException;

public class Test01 {

	public static void main(String[] args) throws IOException {
		//1.创建流对象
		FileOutputStream fos = new FileOutputStream("ggc.txt");
		
		//2.写入数据
		//fos.write(97);
		//fos.write("abcdef".getBytes());//写入字节数组
		  fos.write("abcdef".getBytes(), 1,3);//写入字节数组、偏移量、长度
		
		//3.关闭资源
		fos.close();
	}
}

2.文件不存在的情况下

经验:所有的输出流,当文件不存在时都会创建文件

3.在末尾追加内容

import java.io.FileOutputStream;
import java.io.IOException;

public class Test02 {

	public static void main(String[] args) throws IOException {
		
		//1.创建流对象+ 在末尾追加内容
		FileOutputStream fos = new FileOutputStream("ggc.txt",true);
		
		//2.写入数据
		fos.write("abcdefgh".getBytes());//写入字节数组
		
		//3.关闭资源
		fos.close();
	}
}

4.积极处理异常

import java.io.FileNotFoundException;
/**
 * 知识点:利用文件字节输出流 向文件写入数据
 * 
 * 需求:利用文件字节输出流 向文件写入数据
 * 		1)文件存在的情况下
 * 		2)文件不存在的情况下
 * 			经验:所有的输出流,当文件不存在时都会创建文件
 * 		3)在末尾追加内容
 */
import java.io.FileOutputStream;
import java.io.IOException;

public class Test03 {

	public static void main(String[] args)  {
		
		//1.创建流对象+ 在末尾追加内容
		FileOutputStream fos = null;
		try {
			//1.创建流对象+ 在末尾追加内容
			fos = new FileOutputStream("ggc.txt",true);
			//2.写入数据
			fos.write("abcdefgh".getBytes());//写入字节数组
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//3.关闭资源
			if (fos != null) {
			
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
				}
			}
		}	
		
	}
}

四、利用文件字节输入流 读取文件里的数据

1.文件存在的情况下,并且一个字节一个字节的读取

import java.io.FileInputStream;
import java.io.IOException;

public class Test04 {

	public static void main(String[] args) throws IOException {
		//1.创建流对象
		FileInputStream fis = new FileInputStream("ggc.txt");
		
		//2.读取数据
		//read() -- 读取一个字节,如果读取到文件末尾则返回-1
		int read = fis.read();
		System.out.println((char)read);
		read = fis.read();
		System.out.println((char)read);
		read = fis.read();
		System.out.println((char)read);
		read = fis.read();
		System.out.println(read);
		
		fis.close();
	}
}

2.一个字节一个字节循环读取

import java.io.FileInputStream;
import java.io.IOException;

public class Test05 {

	public static void main(String[] args) throws  IOException{
	//1.创建流对象
	FileInputStream fis = new FileInputStream("ggc.txt");
	//2.读取数据
	//read() -- 读取一个字节,如果读取到文件末尾则返回-1
	int read;
	while ((read = fis.read()) != -1) {
		System.out.println((char)read);
	}
	//3.关闭资源
	fis.close();
	}
}

3.文件不存在的情况下

经验:所有的输入流,当文件不存在都会报FileNotFoundException(文件文找到异常)

4.指定字节数组的循环读取

import java.io.FileInputStream;
import java.io.IOException;

public class Test06 {

	public static void main(String[] args) throws IOException {
		//1.创建流对象
		FileInputStream fis = new FileInputStream("ggc.txt");
		
		//2.读取数据
		//read(bs) -- 读取bs数组长度的数据,将数据存入到bs中并返回有效字节数,如果读取到文件末尾则返回-1
		byte[] bs = new byte[1024];
		int len;
		while ((len = fis.read(bs)) != -1) {
			//将bs字节数组转换为字符串,从第0个下标开始转换len个长度的字节数据
			System.out.println(new String(bs,0,len));
		}
		//3.关闭资源
		fis.close();
	}
}

5.积极处理异常

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Test07 {

	public static void main(String[] args)  {
		
		FileInputStream fis = null; 
	    try {
	    	//1.创建流对象
			fis = new FileInputStream("ggc.txt");
			//2.读取数据
			//read(bs) -- 读取bs数组长度的数据,将数据存入到bs中并返回有效字节数,如果读取到文件末尾则返回-1
			byte[] bs = new byte[1024];
			int len;
			while ((len = fis.read(bs)) != -1) {
				//将bs字节数组转换为字符串,从第0个下标开始转换len个长度的字节数据
				System.out.println(new String(bs,0,len));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//3.关闭资源
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

6.拷贝文本文件

思路:读取源文件,写入目标文件

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy01 {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("IO笔记.txt");
		FileOutputStream fos = new FileOutputStream("copy.txt");
		
		int read;
		while ((read = fis.read()) != -1) {
			fos.write(read);
		}
		
		fis.close();
		fos.close();
	}
}

7.拷贝视频文件

读取源文件,写入目标文件

方案一

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy02 {

	public static void main(String[] args){
		
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("测试视频.mp4");
			fos = new FileOutputStream("copy.mp4");
			
			byte[] bs = new byte[2048];
			int len;
			while ((len = fis.read(bs)) != -1) {
				fos.write(bs,0,len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if (fos != null) {
					try {
						fos.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				
			}
		}

	}
}

方案二

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy03 {

	public static void main(String[] args) throws IOException {
		
		FileInputStream fis = new FileInputStream("测试视频.mp4");
		FileOutputStream fos = new FileOutputStream("copy.mp4");
		
		byte[] bs = new byte[2048];
		int len;
		while ((len = fis.read(bs)) != -1) {
			fos.write(bs,0,len);
		}
		
		fis.close();
		fos.close();
	}
}

方案三

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy04 {

	public static void main(String[] args){
		
		try (FileInputStream fis = new FileInputStream("测试视频.mp4");
			FileOutputStream fos = new FileOutputStream("copy.mp4");){
			
			byte[] bs = new byte[1024];
			int len;
			while((len = fis.read(bs)) != -1){
				fos.write(bs, 0, len);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

五、利用带有缓冲区的字节输出流 向文件写入数据

1.文件存在的情况下

2.文件不存在的情况下

经验:所有的输出流,当文件不存在时都会创建文件

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test01 {

	public static void main(String[] args) throws IOException {
		
		//1.创建流的对象
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ggc.txt"));
		
		//2.写入数据
		bos.write("abcdefgh".getBytes());
		
		//3.关闭资源
		bos.close();
	}
	
}

3.在末尾追加内容

经验:考虑基础流的构造方法

4.积极处理异常

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test02 {

	public static void main(String[] args){
		
		BufferedOutputStream bos = null;
		try {
			//1.创建流的对象
			bos = new BufferedOutputStream(new FileOutputStream("ggc.txt"));
			//2.写入数据
			bos.write("abcdefgh".getBytes());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			//3.关闭资源
			if (bos != null) {
			
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	
	}
}

5.研究带有缓冲区的字节输出流为什么效率高?

效率高:减少了程序与硬盘交互的次数

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test03 {

	public static void main(String[] args) throws  IOException{
		
		//fos与文件交互了3次
		FileOutputStream fos = new FileOutputStream("ggc.txt");
		fos.write("abc".getBytes());//写入文件
		fos.write("def".getBytes());//写入文件
		fos.write("ghi".getBytes());//写入文件
		fos.close();
		
		//bos与文件交互了1次
		
				//创建带有缓冲区的字节输出流 --- 默认缓冲区为:byte[] buf = new byte[8192];
//		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ggc.txt"));		bos.write("abc".getBytes());//写入缓冲区
//		bos.write("def".getBytes());//写入缓冲区
//		bos.write("ghi".getBytes());//写入缓冲区
//		bos.flush();//将数组中的数据全部刷新到文件中(就算不刷新,关闭流的时候也刷新了)
//		bos.close();//将数组中的数据全部写入文件中
		
		//创建带有缓冲区的字节输出流 --- 自定义缓冲区为:byte[] buf = new byte[2048];
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("ggc.txt"),2048);
		bos.write("zxc".getBytes());//写入缓冲区
		bos.write("sdf".getBytes());//写入缓冲区
		bos.write("ryy".getBytes());//写入缓冲区
		bos.flush();//将数组中的数据全部刷新到文件中(就算不刷新,关闭流的时候也刷新了)
		bos.close();//将数组中的数据全部写入文件中
	}
}

六、利用带有缓冲区的字节输入流 读取文件中的数据

1.带有缓冲区的字节输入流使用

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Test04 {

	public static void main(String[] args) throws IOException {
		
		
		//1.创建流对象 -- 默认缓冲区:byte[] buf = new byte[8192];
//		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("hhy.txt"));
		
		//1.创建流对象 -- 自定义缓冲区:byte[] buf = new byte[2048];
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ggc.txt"),2048);
		//2.读取数据
		byte[] bs = new byte[1024];
		int len;
		while ((len = bis.read(bs)) != -1) {
			System.out.println(new String(bs, 0, len));
		}
		//3.关闭资源
		bis.close();
		
	}
}

2.拷贝视频文件

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Copy {

	public static void main(String[] args) throws IOException {
		
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("测试视频.mp4"));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp4"));
		
		byte[] bs = new byte[1024];
		int len;
		while ((len = bis.read(bs)) != -1) {
			bos.write(bs, 0, len);
		}
		bis.close();
		bos.close();
	}
}

七、字节流总结

应用场景:处理二进制文件(图片、音频、视频)

abstract class InputStream --- 字节输入流的基类(抽象类)
abstract class OutputStream -- 字节输出流的基类(抽象类)

class FileInputStream extends InputStream --- 文件字节输入流
class FileOutputStream extends OutputStream - 文件字节输出流

class FilterInputStream extends InputStream --- 过滤器字节输入流
class FilterOutputStream extends OutputStream - 过滤器字节输出流

class BufferedInputStream extends FilterInputStream --- 带有缓冲区的字节输入流
class BufferedOutputStream extends FilterOutputStream - 带有缓冲区的字节输出流
缓冲区大小为:8192字节

你可能感兴趣的:(Java基础,java,服务器,算法,学习,数据结构)