java基础知识--IO的的常用操作(二)

这章主要介绍IO相关的常用操作,从我自己这几年的项目经验上来看,文件IO操作是最频繁使用到的,必然要介绍文件的字符流IO和字节流IO;其次,在网络传输过程中,需要将外面传输进来的数据放到缓冲区,减少对外访问次数,所以缓冲输入输出流BufferInputStream、BufferOutputStream也是必须要了解的了;最后就是说下面试中可能会问的一些问题,以及解答

文件操作

上一篇文章已经分别介绍了IO分字符流和字节流,至于文件的IO,则有字符流的FileReader、FileWrite,字节流的FileInputStream和FileOutputStream。不过,在介绍这几个类之前,我们先来看看File类,毕竟先把文件找到,才能说读写的事情,是不是

File类

在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。File类不是InputStream、OutputStream或Reader、Writer的子类,因为它不负责数据的输入输出,而专门用来管理磁盘文件与目录。

作用:File类主要用于命名文件、查询文件属性和处理文件目录。

构造函数:

1)File (String   pathname)   

     例:File  f1 = new File("File.txt");  // 创建文件对象f1,指向当前目录下的File.txt文件
2)File (String  parent  ,  String child)

     例: File f2 = new  File(“D:\\dir1","File.txt") ; // 创建文件对象f2,指向D:\\dir1目录下的File.txt文件,注意:D:\\dir1目录事先必须存在,否则会抛异常
3)File (File    parent  , String child)
     例: File  f4 = new File("D:\\dir3");
          File  f5 = new File(f4,"FileTest5.txt");  

         //这种方式,如果D:\\dir3目录不存在则会先创建一个对应于某磁盘文件或目录,跟第二种方式存在 

File对象常用的方法:

       1)public boolean exists( ) 判断文件或目录是否存在
       2)public boolean isFile( ) 判断是文件还是目录 
       3)public boolean isDirectory( ) 判断是文件还是目录
       4)public String getName( ) 返回文件名或目录名
       5)public String getPath( ) 返回文件或目录的路径。
       6)public long length( ) 获取文件的长度
       7)public String[ ] list( ) 将目录中所有文件名保存在字符串数组中返回。

File类中还定义了一些对文件或目录进行管理、操作的方法,常用的方法有:
       1) public boolean renameTo( File newFile );  重命名文件
       2) public void delete( );   删除文件
       3) public boolean mkdir( ); 创建目录

标准的文件获取代码:

public class Test {	
    public static void main(String[] args) throws IOException {
		public static void main(String[] args) throws IOException {
		// 如果不存在这个目录,则创建
		File dir = new File("d:\\test");  
        if (!dir.exists())  
        	dir.mkdir();
        
        // 如果这个文件不存在,则创建
        File f= new File(dir,"text.txt");
        if(!f.exists())   
        {   
        	f.createNewFile();   
        }
        
        System.out.println("f1's AbsolutePath=  " + f.getAbsolutePath());  
        System.out.println("f1 Canread=" + f.canRead());  
        System.out.println("f1's len= " + f.length());  
        String[] FL;
        int count = 0;
        FL = dir.list();
        for (int i = 0; i < FL.length; i++) {
            count++;  
            System.out.println(FL[i] + "is in d:\\test");  
        }  
        System.out.println("there are" + count + "file in d:\\test");  
	}
}

字节流方式读写文件

上一篇博客已经介绍了字节流的文件读写FileInputStram和FileOutputStream,FileInputStream可以使用read()方法一次读入一个字节,并以int类型返回,或者是使用read()方法时读入至一个byte数组,byte数组的元素有多少个,就读入多少个字节。在将整个文件读取完成或写入完毕的过程中,这么一个byte数组通常被当作缓冲区,因为这么一个byte数组通常扮演承接数据的中间角色。FileOutputStream则用来处理以文件作为数据输出目的数据流,或者说是从内存区读数据入文件。

比如需要从一个text1.txt文件,将内容复制到另外一个text2.txt文件:

public class Test {
	public static void main(String[] args) throws IOException {
		// 如果不存在这个目录,则创建
		File dir = new File("d:\\test");
        if (!dir.exists()) {  
        	return;
        }
        
        // 如果这个文件不存在,则直接返回
        File f1= new File(dir,"text1.txt");
        if(!f1.exists()) {
        	return;
        }
        
        // 如果这个文件不存在,则创建
        File f2= new File(dir,"text2.txt");
        if(!f2.exists()) {
        	f2.createNewFile();
        }
        
        FileInputStream finS = new FileInputStream(f1);
        FileOutputStream foutS = new FileOutputStream(f2);
        int c;
        while ((c = finS.read()) != -1) {
            foutS.write(c);
        }
        finS.close();
        foutS.close();
	}
}

字符流方式操作文件

字符流方式处理文件其实要考虑比较多的问题,比如是否涉及字节码的转换,由于读到内存中是从源文件的字节编码格式,转换成Unicode格式,再从unicode格式转换到目标文件字节编码格式,所以需要两边都支持这种字节码转换才能使用该方式操作,否则就会出现乱码的问题

public class Test {
	public static void main(String[] args) throws IOException {
		// 如果不存在这个目录,则创建
		File dir = new File("d:\\test");
        if (!dir.exists()) {  
        	return;
        }
        
        // 如果这个文件不存在,则直接返回
        File f1= new File(dir,"text1.txt");
        if(!f1.exists()) {
        	return;
        }
        
        // 如果这个文件不存在,则创建
        File f2= new File(dir,"text2.txt");
        if(!f2.exists()) {
        	f2.createNewFile();
        }
        
        FileReader fr = new FileReader(f1);
        BufferedReader bf = new BufferedReader(fr);
        FileWriter fw = new FileWriter(f2);  
        BufferedWriter bout = new BufferedWriter(fw);  
        String s;
        while ((s = bf.readLine()) != null) {  
            bout.write(s, 0, s.length());  
        }
        bout.flush(); // 这行很关键,如果不加这行,则文件内容无法从缓冲区刷到文件上
        
        bout.close();
        fw.close();
        bf.close();
        fr.close();
	}
}

缓冲输入输出流 BufferedInputStream/BufferedOutputStream

计算机访问外部设备非常耗时。访问外部(键盘、网络)的频率越高,造成CPU闲置的概率就越大。为了减少访问外部的次数,应该在一次对外部的访问中,读写更多的数据。为此,除了程序和流节点间交换数据必需的读写机制外,还应该增加缓冲机制。缓冲流就是每一个数据流分配一个缓冲区,一个缓冲区就是一个临时存储数据的内存。这样可以减少访问外部的次数,提高传输效率。

BufferedInputStream:当向缓冲流写入数据时候,数据先写到缓冲区,待缓冲区写满后,系统一次性将数据发送给输出设备。

BufferedOutputStream :当从向缓冲流读取数据时候,系统先从缓冲区读出数据,待缓冲区为空时,系统再从输入设备读取数据到缓冲区。

键盘输入流读到内存

将BufferedReader与标准的数据流相接 :

import java.io.*;  

public class ReadWriteToFile {  
    public static void main(String args[]) throws IOException {  
        InputStreamReader sin = new InputStreamReader(System.in);  
        BufferedReader bin = new BufferedReader(sin);
        FileWriter out = new FileWriter("myfile.txt");  
        BufferedWriter bout = new BufferedWriter(out);  
        String s;  
        while ((s = bin.readLine()).length() > 0) {
            bout.write(s, 0, s.length());  
        }  

    }  
}

面试题汇总

(1)java中有几种类型的流?
字符流和字节流。字节流继承inputStream和OutputStream,字符流继承自InputSteamReader和OutputStreamWriter。

(2)谈谈Java IO里面的常见类,字节流,字符流、接口、实现类、方法阻塞
答:输入流就是从外部文件输入到内存,输出流主要是从内存输出到文件。
IO里面常见的类,第一印象就只知道IO流中有很多类,IO流主要分为字符流和字节流。字符流中有抽象类InputStream和OutputStream,它们的子类FileInputStream,FileOutputStream,BufferedOutputStream等。字符流BufferedReader和Writer等。都实现了Closeable, Flushable, Appendable这些接口。程序中的输入输出都是以流的形式保存的,流中保存的实际上全都是字节文件。
java中的阻塞式方法是指在程序调用改方法时,必须等待输入数据可用或者检测到输入结束或者抛出异常,否则程序会一直停留在该语句上,不会执行下面的语句。比如read()和readLine()方法。

(3)字符流和字节流有什么区别?
要把一片二进制数据数据逐一输出到某个设备中,或者从某个设备中逐一读取一片二进制数据,不管输入输出设备是什么,我们要用统一的方式来完成这些操作,用一种抽象的方式进行描述,这个抽象描述方式起名为IO流,对应的抽象类为OutputStream和InputStream ,不同的实现类就代表不同的输入和输出设备,它们都是针对字节进行操作的。

在应用中,经常要完全是字符的一段文本输出去或读进来,用字节流可以吗?
计算机中的一切最终都是二进制的字节形式存在。对于“中国”这些字符,首先要得到其对应的字节,然后将字节写入到输出流。读取时,首先读到的是字节,可是我们要把它显示为字符,我们需要将字节转换成字符。由于这样的需求很广泛,人家专门提供了字符流的包装类。

底层设备永远只接受字节数据,有时候要写字符串到底层设备,需要将字符串转成字节再进行写入。字符流是字节流的包装,字符流则是直接接受字符串,它内部将串转成字节,再写入底层设备,这为我们向IO设别写入或读取字符串提供了一点点方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值