IO流的使用

学习IO流之前先了解一下File类

File类

封装文件/目录的各种信息,对目录/文件进行操作,但是我们不可以获取到文件/目录中的内容

 //将文件封装为一个File类的对象:
        File f = new File("path+文件名");
 //File.separator属性帮我们获取当前操作系统的路径拼接符号
 //在windows,dos下,系统默认用“\”作为路径分隔符 ,在unix,url中,使用“/”作为路径分隔符。

因为不同的操作系统所以一般建议使用这种方式将文件封装为一个File对象

File f3 = new File("path"+File.separator+"文件名");

File的4种构造函数

	new File(字符串的路径);
	new File(uri);
	new File(String parent, filename);
	new File(File parent, filename);

######常用方法:

		System.out.println("文件是否可读:" + f.canRead());
        System.out.println("文件是否可写:" + f.canWrite());
        System.out.println("文件的名字:" + f.getName());
        System.out.println("上级目录:" + f.getParent());
        System.out.println("是否是一个目录:" + f.isDirectory());
        System.out.println("是否是一个文件:" + f.isFile());
        System.out.println("是否隐藏:" + f.isHidden());
        System.out.println("文件的大小:" + f.length());
        System.out.println("是否存在:" + f.exists());
 
 f.delete();//删除文件或目录
 f.createNewFile();//创建文件

		System.out.println("绝对路径:"+f.getAbsolutePath());
        System.out.println("相对路径:"+f.getPath());
		System.out.println("文件的大小:"+f.length());
        f.mkdir();//创建单层目录
        f.mkdirs();//创建多层目录
        f.getFreeSpace();//剩余空间
        f.getUsableSpace();//使用空间
        f.getTotalSpace();//总空间
		f.getParentFile();//获取父目录
		f.isAbsolute();//是不是绝对路径
		f.lastModified//返回所引用文件最后修改日期, 为自 1970年1月1日0:00 以来的毫秒数

list()方法 : 会返回一个字符数组,将制定路径下的文件或文件夹名字存储到String数组中。因为其返回的是一个String类型的数组

1)、String[] list()

2)、String[] list(FilenameFilter filter)

//list()的用法
		path = new File("E:\\Java");
		list = path.list();
		for(String itemName : list){
			System.out.println(itemName);
		}

		//FilenameFilter 过滤器,文件名称过滤器

        String[] paths = file.list(new FilenameFilter() {
        			//使用匿名内部类
        			@Override
        			public boolean accept(File dir, String name) {
        				// 文件名称以java结尾的文件
        				if (name.endsWith("java")) {
        					return true;
        				}
        				return false;
        			}
        		});
		//lambda表达式
		String[] paths = file.list((File dir, String name) -> name.endsWith("java"));

总结:

创建:
createNewFile():在指定位置创建空文件,成功返回true,如果已存在就不再创建了返回false
mkdir():在指定位置创建目录,这之后创建最后一级目录,如果上级目录不存在就抛出异常.
mkdirs():在指定位置创建目录,这也会创建路径中所有不存在的父目录
renameTo(File dest):重命名文件或文件夹。文件不同时,相当于文件的剪切,剪切的时候不能操作非空文件夹。移动/重命名成功返回true,失败返回false

删除:
delete() :删除一个文件或者空文件夹,如果文件夹不为空,则不能删除,成返回true,失败返回false
deleteOnExit(): 在虚拟机终止时,请求删除此抽象路径名的文件或者目录,保证文件异常时也可以删除文件

判断:
exists():判断指定的文件或者文件夹是否存在
isFile():判断是否是一个文件;如果不存在,则为false
isDirectory():判断是否是一个文件夹
isHidden():判断指定的文件是否是隐藏文件
isAbsolute():判断指定的文件或文件夹是否是在绝对路径下

获取:
getName():获取文件或文件夹名称
getPath():返回的是绝对路径,可以是相对路径,但是目录要指定
getAbsolutePath():获取绝对路径
length():获取文件的大小(字节为单位)
getParent():获取文件的父路径
lastModified():获取文件最后一次修改的时间

注意:
. :一个点表示当前路径
:两个点表示上一级路径

路径问题:
绝对路径:该文件在硬盘上的完整路径;绝对路径一般是以盘符开头的。
相对路径:资源文件相对于当前程序所在路径。
**注意:**如果程序当前所在路径与资源文件不再同一个盘下面,是没法写相对路径的

案例遍历磁盘:

	public static void find(File file) {
		if (file.isFile()) {
			System.out.println(file.getAbsolutePath());
		} else {
			File[] fs = file.listFiles();
			if (fs != null) {
				for (File file2 : fs) {
					find(file2);
				}
			}
		}
	}

	private void scannerFile(String path) {
		File file = new File(path);
		String[] list = file.list();
		for (String filename : list) {
			String realPath = path + File.separator + filename;
			File ff = new File(realPath);
			if (ff.isFile()) {
				System.out.println(ff.getAbsolutePath());
			} else {
				scannerFile(realPath);
			}
		}
	}

	private void scannerFile1(String path) {
		File file = new File(path);
		File[] list = file.listFiles();
		for (File f : list) {
			if (f.isFile()) {
				System.out.println(f.getAbsolutePath());
			} else {
				scannerFile(f.getAbsolutePath());
			}
		}
	}
字节流

InputStream:字节输入流基类,抽象类是表示字节输入流的所有类的超类。

OutputStream:字节输出流基类,抽象类是表示输出字节流的所有类的超类。

FileInputStream:字节文件输入流,从文件系统中的某个文件中获得输入字节,用于读取诸如图像数据之类的原始字节流。

FileOutputStream:字节文件输出流是用于将数据写入到File,从程序中写入到其他位置。

BufferedInputStream:字节缓冲输入流,提高了读取效率。

BufferedOutputStream:字节缓冲输出流,提高了写出效率。

// 创建输入流 --》 字节输入流
		InputStream is = new FileInputStream(new File("path"));
		byte[] buf = new byte[1024];
		int len = -1;
        while ((len = is.read(buf)) != -1) {
                    System.out.write(buf, 0, len);
       	}

		//IO流,打开之后,必须关闭
		if(is!=null){
			is.close();            
        }

注意:IO流中有很多的异常要处理

案例文件的复制

@Test
	void test4() {
		// 文件拷贝
		InputStream is = null;

		OutputStream os = null;

		try {
			is = new FileInputStream("path1");
			os = new FileOutputStream(new File("path2"));
			byte[] buf = new byte[1024];
			int len = -1;
			while ((len = is.read(buf)) != -1) {
				os.write(buf, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

BufferedInputStream和BufferedOutputStream的使用与FileInputStream和FileOutputStream类似

注意使用BufferedInputStream和BufferedOutputStream一定要关流

			// 刷新缓冲区
			bos.flush();

#####字符流

Reader:读取字符流的抽象类.

Writer:写入字符流的抽象类.

InputStreamReader:字节流转字符流,它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

OutputStreamWriter:字节流转字符流。

BufferedReader:字符缓冲流,从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

BufferedWriter:字符缓冲流,将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

FileReader:InputStreamReader类的直接子类,用来读取字符文件的便捷类,使用默认字符编码。

FileWriter:OutputStreamWriter类的直接子类,用来写入字符文件的便捷类,使用默认字符编码。

注意字符流存在编码的

@Test
	void test() {
		FileReader fr = null;
		try {
			fr = new FileReader("path");

			fr.read();
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			char[] buf = new char[1024];
			int len = -1;
			while ((len = fr.read(buf)) != -1) {
				// 字符数组转换为字符串
				String string = new String(buf, 0, len);
				System.out.println(string);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fr.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

@Test
	void test() {
		FileWriter fw = null;
		try {
			fw = new FileWriter("path");
		} catch (IOException e) {
			e.printStackTrace();
		}
		String msg = "";

		try {
			fw.write(msg.toCharArray());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

@Test
	void test() {

		BufferedWriter bw = null;
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader("path1"));
			bw = new BufferedWriter(new FileWriter("path2"));

			String s = null;
			while ((s = br.readLine()) != null) {
				// 解决换行问题

				// 1、 bw.write(s+"\n");
				// 2、
				bw.write(s);
				bw.newLine();
                
                //3、PrintWriter使用里面的println()
                
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bw != null) {
				try {
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

readLine()一行一行的读数据

将字节流转换为字符流

br = new BufferedReader(new InputStreamReader(System.in));

equalsIgnoreCase(“exit”);以exit为真

#####数据流

数据流:用来操作基本数据类型和字符串的

DataInputStream:将文件中存储的基本数据类型和字符串 写入 内存的变量中
DataOutputStream: 将内存中的基本数据类型和字符串的变量 写出 文件中

		FileOutputStream fos = new FileOutputStream(f);
        DataOutputStream dos = new DataOutputStream(fos);
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File("path")));

        dos.writeBoolean(false);
        dos.writeDouble(6.9);
        dos.writeInt(82);

写出的类型跟读入的类型 必须 要匹配!

#####对象流

ObjectInputStream:对象输入流,从磁盘等保存介质中读取已经保存的对象数据

ObjectOutputStream:将对象转换为数据,保存起来

在java中,如果要保存对象,必须序列化该对象

把内存中的Java对象转换成平台无关的二进制数据,从而允许把这种二进制数据持久地保存在磁盘上,或通过网络将这种二进制数据传输到另一个网络节点。----》序列化

当其它程序获取了这种二进制数据,就可以恢复成原来的Java对象。----》反序列化

通俗的讲

将我们能看懂的文件内容转换为我们看不懂的: ----》序列化

我们看不懂文件的内容,但是程序是可以看懂的,所以可以写一个程序读文件中内容:----》反序列化


你想要序列化的那个对象对应的类,必须要实现一个接口:

Serializable:接口内部,什么都没有,这种接口叫 标识接口。
起到标识作用,标识什么呢?只要实现这个接口的类的对象才能序列化,否则不可以。

public class Person implements Serializable {}

serialVersionUID:
凡是实现Serializable接口(标识接口)的类都有一个表示序列化版本标识符的静态常量:
private static final long serialVersionUID;

serialVersionUID用来表明类的不同版本间的兼容性。简言之,其目的是以序列化对象进行版本控制,有关各版本反序加化时是否兼容。

如果类没有显示定义这个静态变量,它的值是Java运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化。故建议,显式声明。

简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

被序列化的类的内部的所有属性,必须是可序列化的 (基本数据类型都是可序列化的)

static,transient修饰的属性 不可以被序列化。

防止忘记关流,这个将会自动关流

JDK7 提供新特性:
	try-resource
try(创建需要关闭对象的代码放在这儿){
	
} catch(Exception e) {

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值