IO流操作总结

前言


流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

IO流的分类
根据处理数据类型的不同分为:字符流和字节流

根据数据流向不同分为:输入流和输出流

字符流和字节流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:

(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件,我们将在下面验证这一点。

结论:优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。

输入流和输出流
对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

(一)读写文件API

<1>FileUtils

File file = new File ("D:/test.txt");
//写文件参数说明
//(file-操作文件,
//"test"-写入内容,
//"utf-8"-编码,
//false-是否跟随原先文本,false则为替换文本)
FileUtils.writeStringToFile (file,"test","utf-8",false);
//读取文件
System.out.println (FileUtils.readFileToString (file,"utf-8"));

<2>原生IO流

public void testFile() throws IOException{
	FileInputStream in = null;
	FileOutputStream fs = null;
	String oldPath = "D:/test.txt";
	String newPath = "D:/testNew.txt";
	try {
		//实例化文件,并判断文件是否存在
		File oldfile=new File(oldPath);
		if(oldfile.exists()){
			//初始化文件输入与输出流
			in=new FileInputStream (oldPath);
			fs=new FileOutputStream(newPath, false);
			//定义存放读取数据的数组
			byte[] buffer=new byte[10];
			int length;
			while(true){
				int len=in.read(buffer);//当文件读完,返回-1,否则返回读取文件长度
				/*注:输出读取的当前文件内容方法
				 * String s=new String(buffer);
				 * s.trim();(去除字符串前后两端的空格)
				 */
				if(len==-1)break;
				fs.write(buffer);
			}
			System.out.println("OK");
		}
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	}finally{
		in.close();
		fs.close();
	}
}

<3>SpringBoot中的读写文件
待补充

(二)工作中遇到的问题

<1>classPath读取文件,写文件会写到编译后的文件,而不在resources目录下

//通过读取json,然后修改json中的key值,写回文件(后面发现,读写不是同一路径)
final ClassPathResource resource = new ClassPathResource("test/test.json");
final File filePath = resource.getFile();
String returnString="";
try{
	returnString = FileUtils.readFileToString(filePath, "UTF-8");
	JSONArray jsonArray = new JSONArray (returnString);
	for(int i=0;i<jsonArray.length ();i++){
		if(jsonArray.getJSONObject (i).getString ("key").equals ("test")){
			jsonArray.getJSONObject (i).put ("test","newTestVal");
		}
	}
	returnString = jsonArray.toString ();
}catch (IOException e){
	e.printStackTrace ();
}catch (JSONException e){
	e.printStackTrace ();
}
FileUtils.writeStringToFile (filePath, returnString,"utf-8",false);

解决办法:
若需要写回文件,还是用已知路径进行读写操作,不要用classPath API读取文件。

<2>classPath读取文件,打包成jar包或者war包后,路径会出现异常。

final ClassPathResource resource = new ClassPathResource("test/test.json"); 
//本地运行没错,在jar包中运行路径不正确,导致 
//java.lang.IllegalArgumentException: URI is not hierarchical
final File filePath = resource.getFile();
try{
    returnString = FileUtils.readFileToString(filePath, "UTF-8");
}catch (IOException e){
    e.printStackTrace ();
}

解决办法:

String returnString = "",line;
try{
    Class clazz = this.getClass();
    //InputStream路径在开发环境和jar包内都是一致的
    InputStream in = clazz.getClassLoader().getResourceAsStream("test/test.json");
    InputStreamReader inputStreamReader = new InputStreamReader (in);
    BufferedReader bufferedReader = new BufferedReader (inputStreamReader);
    while((line = bufferedReader.readLine()) != null) {
        returnString += line;
    }
}catch (Exception e){
    e.printStackTrace ();
}
return returnString ;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Funnee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值