java知识点拾遗(IO流-1)

  1. 主要类
  2. File类
  • 名称分隔符
path1="d:/temp/test.txt";
path2="d:"+File.separator+"temp"+File.separator+"test.txt";

//1、构建File对象
File src = new File(path);
System.out.println(src.length());

//2、构建File对象
src = new File("D:/java300/IO_study01","IO.png");
src = new File("D:/java300/","IO_study01/IO.png");
System.out.println(src.length());

//3、构建File对象
src = new File(new File("D:/java300/IO_study01"),"IO.png");
System.out.println(src.length());
  • 路径基本信息
//用户目录
System.out.println(System.getProperty("user.dir"));
//取得绝对路径
src = new File("IO.png");
System.out.println(src.getAbsolutePath());

File src = new File("IO_study01/IO.png");
		
//基本信息
System.out.println("名称:"+src.getName());
System.out.println("路径:"+src.getPath());
System.out.println("绝对路径:"+src.getAbsolutePath());
System.out.println("父路径:"+src.getParent());
System.out.println("父对象:"+src.getParentFile().getName());

//文件状态
src = new File("xxx");
if(null == src || !src.exists()) {
	System.out.println("文件不存在");
}else {
	if(src.isFile()) {
		System.out.println("文件操作");
	}else { //src.isDirectory()
		System.out.println("文件夹操作");
	}
}

//获取文件的长度字节数(文件夹返回0)
File src = new File("D:/java300/IO_study01/IO.png");
System.out.println("长度:"+ src.length());

//文件操作
//createNewFile()  : 不存在才创建,存在创建失败,只能创建文件
//delete():删除已经存在的文件
//操作系统的设备名不能作为文件名创建
File src = new File("D:/java300/IO_study01/io.txt");
boolean flag =src.createNewFile();
System.out.println(flag);
flag = src.delete();
System.out.println(flag);
  • 创建目录
//1、mkdir() : 确保上级目录存在,不存在创建失败
//2、mkdirs(): 上级目录可以不存在,不存在一同来创建

File dir = new File("D:/java300/IO_study01/dir/test");
//创建目录 mkdirs()
boolean flag = dir.mkdirs();
System.out.println(flag);
//创建目录 mkdir()
dir = new File("D:/java300/IO_study01/dir/test2");
flag = dir.mkdirs();
System.out.println(flag);
  • 列出目录信息
File dir = new File("D:/java300/IO_study01");
		
//下级名称  list
String[] subNames = dir.list();
for(String s:subNames) {
	System.out.println(s);
}

//下级对象  listFiles()
File[] subFiles = dir.listFiles();
for(File s:subFiles) {
	System.out.println(s.getAbsolutePath());
}

//所有盘符
File[] roots = dir.listRoots();
for(File r:roots) {
	System.out.println(r.getAbsolutePath());
}
  • 统计目录的大小(Byte)
public class Test {
	public static void main(String[] args) {
		File src =  new File("D:\\java300\\IO_study01");
		count(src);
		System.out.println(len);
	}
	private static long len =0;
	public static void count(File src) {	
		//获取大小
		if(null!=src && src.exists()) {
			if(src.isFile()) {  //大小
				len+=src.length();
			}else { //子孙级
				for(File s:src.listFiles()) {
						count(s);
				}
			}
		}
	}
}
  1. 字符编码
    Java字符使用16位的双字节存储。
字符集说明
US-ASCIIASCII编码
ISO-8859-1Latin-1 拉丁字符,包含中文,日文等
UTF-8变长Unicode字符(1-3字节),英文字符占1个字节,中文字符占3个字节。
UTF-16BE定长Unicode字符(2字节),Gig-Ending编码:高字节低地址
UTF-16LE定长Unicode字符(2字节),Little-Ending编码:低字节低地址
UTF_16文件的开头指明BE/LE编码方式,即BOM(Byte Order Mark):“FE FF”表示BE编码,“FF FE”表示LE编码

这里ANSI指系统默认的字符集——windows中文环境下默认字符集是GBK。

  • 字符编码
String english = "abc";
String chinese = "将进酒";

byte[] data1 = english.getBytes();
System.out.println("英文\"" + english + "\"的长度:" + data1.length);
byte[] data2 = english.getBytes("GBK");
System.out.println("英文\"" + english + "\"的长度:" + data2.length);

byte[] data3 = chinese.getBytes(); // 默认getBytes("UTF8"),工程字符集,字符集名称大小写均可
System.out.println("中文\"" + chinese + "\"的长度:" + data3.length);
byte[] data4 = chinese.getBytes("GBK");
System.out.println("中文\"" + chinese + "\"的长度:" + data4.length);
  • 字符解码
    String–>byte[]:编码
    byte[] -->String:解码
String str1 = "米国USA";
byte[] data = str1.getBytes();

String str2 = new String(data, 0, data.length, "gbk");
System.out.println(str2);
String str3 = new String(data, "utf8");
System.out.println(str3);
  • 乱码的原因

    • 字节数不够
    • 编码字符集不匹配
  • 中文字符集
    cp936<gb2312<bgk

  1. IO流
  • 字节流
    InputStream/OutputStream

  • 字符流
    Reader/Writer

  • 读操作步骤(概念)

//1、创建源
File src = new File("abc.txt");
//2、选择流
try {
	InputStream  is =new FileInputStream(src);
	//3、操作 (读取)
	int data1 = is.read(); //第一个数据s
	int data2  = is.read(); //第二个数据x
	int data3  = is.read(); //第三个数据t
	int data4  = is.read(); //????不是数据,文件的末尾返回-1
	System.out.println((char)data1);
	System.out.println((char)data2);
	System.out.println((char)data3);
	System.out.println(data4);
	//4、释放资源
	is.close();
} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}
  • 操作步骤

字节读

//1、创建源
File src = new File("abc.txt");
//2、选择流
InputStream  is =null;
try {
	is =new FileInputStream(src);
	//3、操作 (读取)
	int temp ;
	while((temp=is.read())!=-1) { //一个字节一个字节地读
		System.out.println((char)temp);
	}		

} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}finally {
	//4、释放资源
	try {
		if(null!=is) {
			is.close();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}

块读

//1、创建源
File src = new File("abc.txt");
//2、选择流
InputStream  is =null;
try {
	is =new FileInputStream(src);
	//3、操作 (分段读取)
	byte[] flush = new byte[1024*10]; //缓冲容器
	int len = -1; //接收长度
	while((len=is.read(flush))!=-1) {
		//字节数组-->字符串 (解码)
		String str = new String(flush,0,len); //String str = new String(flush, "utf8");
		System.out.print(str);
	}		

} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}finally {
	//4、释放资源
	try {
		if(null!=is) {
			is.close();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}
  • 写操作
//1、创建源
File dest = new File("dest.txt");
//2、选择流
OutputStream os =null;
try {
	os = new FileOutputStream(dest,true); //true表示追加写入
	//3、操作(写出)
	String msg ="IO is so easy\r\n";
	byte[] datas =msg.getBytes(); // 字符串-->字节数组(编码,默认字符集)
	//byte[] datas  = msg.getBytes("utf8"); 按照utf8字符集编码
	os.write(datas,0,datas.length); //或者out.write(datas);
	os.flush();
}catch(FileNotFoundException e) {		
	e.printStackTrace();
}catch (IOException e) {
	e.printStackTrace();
}finally{
	//4、释放资源
	try {
		if (null != os) {
			os.close();
		} 
	} catch (Exception e) {
	}
}
  • 释放资源
    先打开的后关闭,后打开的先关闭。
    可以利用Closeable接口封装释放资源的动作。
public static void close(Closeable... ios) {
	for(Closeable io:ios) {
		try {
			if(null!=io) {
				io.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

或者可以利用try …with…resources自动资源释放(JDK7之后)

try(is;os) { //<----------is和os自动释放			
或者
try( InputStream is=new FileInputStream(src);
     OutputStream os=new FileOutputStream(dest);){
     
	......
	......
}catch(FileNotFoundException e) {		
	e.printStackTrace();
}catch (IOException e) {
	e.printStackTrace();
}
  • 纯文本处理
    FileReader/FileWriter(内置解决字符编解码问题)
    append()返回Writer,故可以实现链式引用。

块读

//1、创建源
File src = new File("abc.txt");
//2、选择流
Reader  reader =null;
try {
	reader =new FileReader(src);
	//3、操作 (分段读取)
	char[] flush = new char[1024]; //缓冲容器,注意是字符数组不是字节数组
	int len = -1; //接收长度
	while((len=reader.read(flush))!=-1) {
		//字符数组-->字符串,解码无需指定字符集(系统已经处理好了)
		String str = new String(flush,0,len);
		System.out.println(str);
	}		

} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}finally {
	//4、释放资源
	try {
		if(null!=reader) {
			reader.close();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}

块写

//1、创建源
File dest = new File("dest.txt");
//2、选择流
Writer writer =null;
try {
	writer = new FileWriter(dest);
	//3、操作(写出)
	//写法一
	//String msg ="I love you baby\r\n你知道我在等你吗";
	//char[] datas =msg.toCharArray(); // 字符串-->字符数组(不存在编码问题)
	//writer.write(datas,0,datas.length);
	写法二
	String msg ="I love you baby\r\n你知道我在等你吗";
	writer.write(msg);	
	writer.write("add");		
	writer.flush();
	
	//写法三
	//writer.append("I love you baby\r\n").append("你知道我在等你吗");
	//writer.flush();
}catch(FileNotFoundException e) {		
	e.printStackTrace();
}catch (IOException e) {
	e.printStackTrace();
}finally{
	//4、释放资源
	try {
		if (null != writer) {
			writer.close();
		} 
	} catch (Exception e) {
	}
}
  • 字节数组流
    ByteArrayInputStream&ByteArrayOutputStream,在内存中,Java可以直接访问,无需关闭。

  • 处理流
    使用了装饰模式。

    装饰器类包裹/包装基本类。接口方法(产生多态行为)从装饰器类向基本类方向层层调用,然后由内层的基本类向外部的包装类层层返回。抽象类实现接口,但主要是要提供公共属性。

  1. 流的缓冲
  • 提供缓冲的装饰流类可以提高IO性能。
  • 控制流的基础是节点流,底层不能没有节点流。
  • 释放外层装饰器流类的对象,则内层的基本流类对象资源会自动释放。释放是从里到外依次释放。

这里节点流是基本IO流类,而控制流是装饰器IO流类。装饰器IO流类提供流的缓冲提升IO效能。控制流类包装节点流类——装饰器类包装基本类。
示例如下:

File src = new File("abc.txt");
...
is=new BufferedInputStream(new FileInputStream(src));
          装饰器类                   基本类
          控制流类                   节点流类
          提升IO效能
          后释放(手动)             先释放(自动)
-------------------------------------------------------------------
File dest = new File("dest.txt");
...
os =new BufferedOutputStream( new FileOutputStream(dest));
          装饰器类                   基本类
          控制流类                   节点流类
          提升IO效能
          后释放(手动)             先释放(自动)
  1. 字符输入输出加入缓冲流
  • 读入
//1、创建源
File src = new File("abc.txt");
//2、选择流
BufferedReader  reader =null;
try {
	reader =new BufferedReader(new FileReader(src));
	//3、操作 (分段读取)
	String line =null;
	while((line=reader.readLine())!=null) {
		//字符数组-->字符串
		System.out.println(line);
	}		

} catch (FileNotFoundException e) {
	e.printStackTrace();
} catch (IOException e) {
	e.printStackTrace();
}finally {
	//4、释放资源
	try {
		if(null!=reader) {
			reader.close();
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}
  • 写出
//1、创建源
File dest = new File("dest.txt");
//2、选择流
BufferedWriter writer =null;
try {
	writer = new BufferedWriter(new FileWriter(dest));
	//3、操作(写出)			
	writer.append("I love you baby");
	writer.newLine(); //输出一个\r\n
	writer.append("偏偏喜欢你");
	writer.flush();
}catch(FileNotFoundException e) {		
	e.printStackTrace();
}catch (IOException e) {
	e.printStackTrace();
}finally{
	//4、释放资源
	try {
		if (null != writer) {
			writer.close();
		} 
	} catch (Exception e) {
	}
}
  1. 转换流
    CharactorStreams—>InputStreamReader/OutputStreamWriter—>ByteStreams

InputStreamReader/OutputStreamWriter能将字节流转换为字符流,并且能为字节流指定字符集。

InputStreamReader对应解码;OutputStreamWriter对应编码。

  • 将字节流转换成字符流
//操作System.in 和System.out
try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter writer =new BufferedWriter(new OutputStreamWriter(System.out));){
	//循环获取键盘的输入(exit退出),输出此内容
	String msg ="";
	while(!msg.equals("exit")) {
		msg = reader.readLine(); //循环读取
		writer.write(msg); //循环写出
		writer.newLine();
		writer.flush(); //强制刷新。不强制刷新,在缓存未满时不输出,卡在上一步。
	}
}catch(IOException e) {
	System.out.println("操作异常");
}
  • 处理指定字符集
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;

public class ConvertTest {
	public static void main(String[] args) {
		try(BufferedReader reader =
				new BufferedReader(
						new InputStreamReader(
								new URL("http://www.baidu.com").openStream(),"UTF-8"));
			BufferedWriter writer =
				new BufferedWriter(
					new OutputStreamWriter(
						new FileOutputStream("baidu.html"),"UTF-8"));){
			//3、操作 (读取)
			String msg ;
			while((msg=reader.readLine())!=null) {
				//System.out.println(msg);
				writer.write(msg); //如果字符集不统一将出现乱码
				writer.newLine();
			}					
			writer.flush();
		}catch(IOException e) {
			System.out.println("操作异常");
		}	
	}
}
  1. 数据流
    DataInputStream/DataOutputStream保存了数据及其类型。
//写出
ByteArrayOutputStream baos =new ByteArrayOutputStream();
DataOutputStream dos =new DataOutputStream(new BufferedOutputStream(baos));
//操作数据类型 + 数据
dos.writeUTF("白日依山尽");
dos.writeInt(18);
dos.writeBoolean(false);
dos.writeChar('a');
dos.flush();
byte[] datas =baos.toByteArray();
System.out.println(datas.length);
//读取
DataInputStream dis =new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(datas)));
//顺序与写出一致
String msg = dis.readUTF(); 
int age = dis.readInt();
boolean flag = dis.readBoolean();
char ch = dis.readChar();
System.out.println(flag);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值