IO流小结之一:File与FileWriter常见问题与方法

本文详细介绍了Java中File和FileWriter的使用,包括它们创建文件的过程、异常处理、文件续写与换行注意事项,以及字符流的默认编码和读取方式。重点讲解了如何通过FileWriter实现文件的追加与换行,以及FileReader的读取策略,包括使用字符数组提高读取效率。同时,文章提供了文件复制的实例代码。


         一、file和filewriter操作的文件地址在哪儿,创建文件的过程是怎么样的?

                 通过File file =new File(“filepath”);来创建文件时,在目录下不会立刻生成对应的文件,但此时file对象引用已经获得一个和filepath一样的地址,   通过file创建文件目录时,不会覆盖之前已经存在的文件夹,是一种合并方式的创建。      

           使用FileWriter时会自动判断是否在制定目录下寻在相应的文件的,如果不存在则自动创建一个,通过filewriter创建文件时会把之前同名的文件替换,是一种覆盖式的创建。 

            在eclipse中,通过filewriter创建的文件,如果前面不包含文件的绝对地址,则创建的位置是在eclipse的工作空间的位置,eclipse的工作空间workspace可以通过软件的file窗口中选择替换工作空间来指定位置;

             file和filewriter方法本身都不会主动执行,file需要借助使用.mkdirs();方法,而filewriter需要借助.flush();方法(.close()方法也包含了flush的方法);

      二、io字符流中的异常情况以及异常产生的原理

            针对file字符流的操作,有两个基类,分别是Writer和Reader,由此派生的两个子类分别是FileWriter和FileReader;当我们需要用到字符流的操作时,首先需要在程序中导入Io类,通常可以用import java.io,*;

            由于io操作伴随着异常,所以需要在程序中抛出异常申明或者使用异常捕获方式来处理IO异常;常见的异常包括ionotfoundexception,这就是常见的找不到文件的异常,特别需要提一下的是,Exception in thread "main" java.lang.StringIndexOutOfBoundsException: 字符串超出范围的异常,通过eclipse编译提示的信息是String index out of range: -1;我们知道读到一个文件的末尾,会返回-1,表示文件已经读取完毕,如果一个文件里面本来就是空的,没有任何有效字符,那么使用filereader方法时,就会直接返回-1,并提示异常;所以在Io操作时对于异常的处理也非常重要;

            三、filewriter的文件续写以及换行符注意事项

             对于使用filewriter续写文件时,只需要在定义filewriter对象时在文件后面加上一个true,例如,FileWriter fw=new FileWriter("F:\\IOTest\\a\\source.txt",true);那么接下来通过fw.writer("String content");书写的内容就会续写在文件末尾;如果需要让续写的部分主动换行,则需要写入换行符,在windows系统中,换行符使用\r\n表示,在linux系统下只需要使用\n即可,在windows系统中如果只用\n则显示出来的就是小黑块,这主要是因为编码方式差异造成的。

          四、字符流的默认编码及多种读取方式和原理

      字符流不同于字节流,主要是为了方便或提高字符的操作效率,而字符在计算机中的实际表现形式还是二进制,为了达到方便操作的目的,就出现了各种环境下使用的字符编码,对于filereader类,默认的是使用的编码是BGK;

             使用filereader读取文件时,是一个字符一个字符的读取,在程序中为了书写方便合理,通常采用循环的方式读取,以末尾不是-1为标志,例如:

              while(true){


int s=fr.read();  //read()方法返回的是int类型的数据,在显示的需要转换为char型
if(s==-1)break;   //当前读取的数据为-1时跳出while循环,
System.out.print((char)s);
}

            上面的循环方式也可以写为如下结构:


int s=0;
       while((s=fr.read())!=-1)  //当读取的数据不为-1时打印,
{
System.out.print((char)s);
}

             

                由于read()方法具有阻塞性,所以为了加快读取速度,没必要没读取一次就判断一次,实际通常的做法是,定义一个char型数组,然后将read()方法读到的数据直接存到数组中,方法为:read(buff);这个方法会返回int型的数据,代表buff中读到的数据个数,注意,这里是buff中新读到的数据,可能buff中还存有之前的数据,而且每次读取的时候会把新读到的数据从buff的最低位到最高位依次排列覆盖,为了确保有效数据,通常在对buff中的数据进行提取时,会使用到buff的有效数据作为分隔,示例如下:

             char buff[]=new char[1024];//字符串数组的长度通常定义为1024的整数倍
        
             int num=fr.read(buff);     //通过int num来接收buff中读到的数据个数,注意这个num是新读到的数据个数,而不是指buff中所有存在的数据个数;

   
            System.out.print(new String(buff,0,num));  //在控制台显示buff中的数据,以一个buff长度为界,为了避免打印大文件时出现不必要的格式问题,这里最好使用print而不是println,new String是为利用String中的字符串操作方法,以便能控制打印的有效数据长度;如果直接打印buff,则会按照buff数组的长度打印出来,有效数据之后就是空格。

        五、通过filereader和filewriter实现文本复制

               File file = nefilw File("F:\\IOTest\\c\\filecopy");

file.mkdirs();
 FileReader fr=new FileReader("F:\\IOTest\\a\\source.txt");定义需要被复制的文件
 char []sd=new char[1024];
 int num=fr.read(sd);    //读取被复制的文件到数组中,并获得文件的长度

 
 FileWriter fw=new FileWriter("F:\\IOTest\\c\\filecopy\\filecopy01.txt");//定义需要创建的备份文件,名字不一样
fw.write(sd,0,num);//向备份文件中写入数据,长度和被复制文件一样,如果不加上0,num则会按照buff的长度进行复制,
fw.close();  刷新发送流并关闭流资源。

备注:

public String(char[] value,
              int offset,
              int count)
 
分配一个新的 String,它包含取自字符数组参数一个子数组的字符。 offset 参数是子数组第一个字符的索引, count 参数指定子数组的长度。该子数组的内容已被复制;后续对字符数组的修改不会影响新创建的字符串。

参数:
value - 作为字符源的数组。
offset - 初始偏移量。
count - 长度。
抛出:
IndexOutOfBoundsException - 如果 offsetcount 参数索引字符超出 value 数组的范围。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值