Java之IO

File

  1. 介绍:IO包中唯一表示文件和目录的路径的对象的类。
  2. 特点:只能获取和设置文件本身的信息,不能获取和设置文件的内容。
  3. 功能:创建、删除、重命名、查询状态、判断类型等
  4. 路径分隔符 String pathSeparator = File.pathSeparator();//不常用
    Windows:"\","/"
    Unix:"/"
  5. 属性分隔符 String separator = File.separator();
    Windows:";"
    Unix:":"
  6. 注意:
    Unix严格区分大小写,Windows默认情况下不区分大小写。
    Java中"\“是转义字符,如果使用”\“需要写为”\\",但是因为两种系统都支持"/“的写法,故通常使用”/"。

需求:列出指定目录的所有文件。

public void listAllFile(File file){
	File[] files = file.listFiles();//列出该目录的所有File对象
	for(File f : files){
		System.out.println(f);
		if(f.isDirectory())//如果该File是目录,递归查看File子目录
			listAllFile(f);
	}
}

FilenameFilter(文件过滤器)

需求:得到指定目录下所有以.java结尾的文件。

public File[] fileFilter(File file){
	File[] files = file.listFiles(new FilenameFilter(){//文件过滤器
		public boolean accept(File dir,String name){
			return new File(dir,name).isFile() && name.endWith(".java");
		}
	});
	return files;
}

IO流

四大基流

在这里插入图片描述
四大基流都是抽象类,其他流都是基流的实现类。

文件流

文件字节输入流:FileInputStream
文件字节输出流:FileOutputStream new FileOutputStream(file,true);//表示文件追加
文件字符输入流:FileReader
文件字符输出流:FileWriter new FileWriter(file,true);//表示文件追加

注意
1、不要用字节流来处理字符。
2、String类中getBytes()方法可以把字符串转为byte数组。
3、关于flush()方法,字符流都有用,字节流只有缓冲流有用。
4、输入输出都应当使用字节/字符缓冲数组

缓冲流

字节缓冲输入流:BufferedInputStream
字节缓冲输出流:BufferedOUtputStream
字符缓冲输入流:BufferedReader
字符缓冲输出流:BufferedWriter

优点
1、缓冲流比节点流效率高
2、有机会回滚写入的数据
注意
1、默认缓冲区大小8192(8*1024)

转换流

InputStreamReader:把字节输入流转换为字符输入流
OutputStreamWriter:把字节输出流转换为字符输出流

问题:为什么有字节转换流没有字符转换流?因为字符流是字节流的增强,操作文本时字符流更为有效。

打印流

字节打印流:PrintStream
字符打印流:PrintWriter

注意:PrintWriter可以启用自动刷新。new PrintWriter(new FileOutputStream(file),true);
启用自动刷新之后,调用println、printf、format方法才有效。

对象流(序列化和反序列化)

序列化:把内存中的对象数据存储到磁盘文件或在网络上传输ObjectInputStream
反序列化:把磁盘文件或在网络上传输的数据解析成内存中的数据ObjectOutputStream
注意:如果抛NotSerializableException,表示序列化的对象没有实现Serializable接口。

需要做序列化的对象的类,必须实现序列化接口:java.io.Serializable接口(标志接口[没有抽象方法]).
底层会判断,如果当前对象是Serializable的实例,才允许做序列化. 对象 instanceof Serializable;

问题
1、为什么需要序列化?
1):分布式系统中,需要共享的JavaBean对象,得做序列化后在网络上传输。
2):服务钝化:发现某些对象很久没有活动,服务器会把这些对象,持久化在本地磁盘文件。
2、如果某些数据不需要序列化(如:密码),怎么办?
transient String password;//瞬态字段
3、反序列化时需要提供对象的class文件,但class文件可能会变化(增加新的字段),如何保证版本兼容问题?
如果不显示定义serialVersionUID变量,该变量的值由JVM根据类相关信息计算,而修改后的类和之前不同,所以会出现不兼容问题(InvalidClassException)。解决方法是在类中提供一个固定的serialVersionUID。private static final long serialVersionUID = 1L

随意访问文件(RandomAccessFile)

常使用于多线程下载和断点下载

RandomAccessFile raf = new RandomAccessFile(file,rw);
//rw:以读写方式打开
//r:以只读方式打开(调用write方法抛出IOException)
raf.seek(0);//设置文件指针为第0个字节
raf.skipBytes(12);//设置文件指针跳过12个字节

管道流

实现两个线程之间的数据交互.

PipedInputStream
PipedOutputStream
PipedReder
PipedWriter

class OutputThread extends Thread{
	private PipedOutputStream out = new PipedOutputStream();
	public PipedOutputStream getOut(){
		return out;
	}
	public void run(){
		//TODO
	}
}
class InputThread extends Thread{
	private PipedInputStream in = null;
	public InputThread(PipedOutputStream out){
		in = new PipedInputStream(out);
	}
	public void run(){
		//TODO
	}
}
class Test{
	public static void main(String[] args){
		OutputThread outThread = new OutputThread();
		InputThread inThread = new InputThread(outThread.getOut());
		outThread.start();
		inThread.start(); 
	}
}

内存流(数组流)

字节内存流:ByteArrayInputStream、ByteArrayOutputStream
字符内存流:CharArrayInputStream、CharArrayOutputStream
字符串流:StringReader、StringWriter

合并流

SequenceInputStream(InputStream in,InputStream otherIn)

标准流的重定向

System.setIn(InputStream in);//修改System.in的源
System.setOut(OutputStream out);//修改System.out的目标

NIO

在这里插入图片描述

Properties类加载文件

Properties类(Hashtable的子类,Map的实现类)

Properties p = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();//得到类加载器,相对路径为bin目录
InputStream inStream = loader.getResourceAsStream("db.properties");
p.load(inStream);

问题:为什么使用配置文件?
防止硬编码,让维护人员不修改源代码也能修改相关信息。(如:数据库连接相关信息)

资源的正确关闭方式

java1.7之前

public void closeStream(File srcFile,File destFile){
	InputStream in = null;
	OutputStream out = null;
	try{
		in = new FileInputStream(srcFile);
		out = new FileOutputStream(destFile);
		//TODO
	}catch(Exception e){
		e.printStackTrace();
	}finally{
		try{
			if(in != null)
				in.close();
		}catch(Exception e){
			e.printStackTrace();
		}
		try{
			if(out != null)
				out.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
//1、将声明放在try外边是因为finally中需要关闭
//2、finally中的判空是防止出现异常时out对象还未实例化导致finally中的close方法出现空指针异常问题。
//3、finally中两个try是防止关闭in时出现异常导致out对象无法关闭

java1.7之后

public void closeStream(File srcFile,File destFile){
	try(
		InputStream in = new FileInputStream(srcFile);
		OutputStream out = new FileOutputStream(destFile);
	){
		//TODO
	}catch(Exception e){
		e.printStackTrace();
	}
}

字符编码

常见字符集:ASCII、ISO-8859-1、GB2312\GBK\GB18030、ANSI、UTF-8、UTF-8 BOM
ISO-8859-1:占一个字节,收录了西欧语言,不能表示汉字
GB2312\GBK\GB18030:占两个字节,支持中文
ANSI:占两个字节,在简体中文操作系统中ANSI就是GB2312
UTF-8:针对Unicode的可变长字符编码
UTF-8 BOM:微软搞出来的编码,空文本也占3个字节,不适用此编码。

注意
1、建议使用UTF-8。
2、存储字母和数字,所有编码都只占一个字节。
3、存储中文,GBK家族占两个字节,UTF-8占3个字节。

编码和解码

byte[] bytes = "hello".getBytes("UTF-8");
new String(bytes,"UTF-8");
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值