i/o-java中级

一,文件对象

几种创建文件对象的方式:绝对路径,相对路径,父目录

二,流

image

1.流的建立(文件流)
文件输入流:FileInputStream=new FileInputStream(f);
文件输出流:FileOutputStream=new FileOutputStream(f);
1.①字节流的读写
拿代码来说明:
创建一个长度为文件长度的字节数组byte[] b=new byte[(int)f.length()];
用字节流的形式将文件内容读入字节数组fis.read(b);
用字节流的形式将内容写入文件 fos.write(b);
*1.②字符流的读写

/*这段代码是创建一个字符输入流,将文件f里的内容读入到all字符数组中*/ 
try(FileReader fr=new FileReader(f)) 
{
char[] all=new char[(int)f.length()];
fr.read(all); }
catch (IOException e) {
e.printStackTrace(); }
/*这段代码是将字符写入文件 */
try(FileWriter fw=new FileWriter(f)){
char[] cs=str.toCharArray //假设str是一个已赋值的字符串 
fw.writer(cs); }
catch (IOException e)
{ e.printStackTrace(); }

1.③缓存流的读写(必须建立在一个存在的流的基础上)
以介质是硬盘为例,字节流和字符流的弊端:
在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。

为了解决以上弊端,采用缓存流。
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

就好比吃饭,不用缓存就是每吃一口都到锅里去铲。用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲

缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作

try( FileReader fr=new FileReader(f);//字符输入流
BufferedReader br=new BufferedReader(fr);//在字符输入流的基础上创建一个缓存输入流
FileWriter fw=new FileWriter(f);//字符输出流
PrintWriter pw=new PrintWriter(fw);//在字符输出流的基础上创建一个缓存输出流 )
{
//读取
while(true){
String line=br.readLine();//读取一行f文件的内容
if(line==null){break;} }
//写入
pw.println("要写入的内容");//可以一次写入一行数据
pw.flush();//有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush
}

*1.④数据流的读写

try(
FileInputStream fis=new FileInputStream(f);
DataInputStream dis=new DataInputStream(fis);
FileOutputStream fos=new FileOutputStream(f);
DataOutputStream dos=new DataOutputStream(fos);
){//写入数据。DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取。
dos.writeBoolean(true);
dos.writeInt(1);//进行读取的时候依次读取,第一个读的整数是1
dos.writeInt(2);//第二个度的整数是2
dos.writeUTF("字符串");
//读取数据。要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException
int x1=dis.readInt();//读到的是1
int x2=dis.readInt();//读到的是2
/*在这里博主产生了一个疑惑,可不可以用数组将所有的数据读进来呢,待会试试*/
boolean b=dis.readBoolead();
String str=dis.readUTF();
}catch(IOException e){
e.printStrackTrace();
}

1.⑤对象流(序列化)

try(
FileInputStream fis=new FileInputStream(f);
ObjectInputStream ois=new ObjectInputStream(fis);
FileOutputStream fos=new FileOutputStream(f);
ObjectOutputStream oos=new ObjectOutputStream(fos);
){
/* 假设有一个类Circle,其本身实现必须Serializable接口,否则无法序列化*/
//将c1写入到文件中去了,也就是对象的序列化。
oos.writeObiect(c1);//c1为一个Circle的引用
//反序列化
/*我想不通一个问题,就是在这里用的都是读写内容比较少的情况,当文件内容多了,如何去读到我们想要的数据*/
Circle c2=(Circle)ois.readObject();
}catch(IOException e){
e.printStrackTrace();
}

2.关闭流的方式
所有的流,无论是输入流还是输出流,使用完毕之后,都应该关闭。 如果不关闭,会产生对资源占用的浪费。 当量比较大的时候,会影响到业务的正常开展。
①在try中关闭:如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患。 不推荐使用,所以不做赘述
②在finally中关闭(标准的关闭方式):
在tyr块外创建流,如果在tyr中声明流,其作用域无法到达finally块中:FileInputStream=null; 在finally中关闭: java finally{ //判断是否为空 if(fis!=null){ //再进行一次trycatch处理 try{fis.close();} catch(IOException e){e.printStackTrace;}}}
③在try中声明流,try,catch或者finally结束的时候,会自动关闭,这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术:

try(FileInputStrean fis=new FileInputStream(f);
FileOutputStream fos=new FileOutputStream(f);)
{ /*此处代码就不举例了*/ } catch(IOException e){ e.printStackTrace(); }
posted @ 2022-06-15 13:10  陈琪[0]  阅读(29)  评论(0)    收藏  举报