Java之IO流

摘要

Java数据在输入/输出时会做连续传递,这点有点像水流,所以Java把数据流称为流(Stream)。最常见的流是在文本模式下,用户输入资料以后。经过处理再将结果打印在屏幕上。另一种流是发生在文件存取:先将文件内容读取到内存,然后再将结果写回文件。输入和输出时相对内存而言:
如图:
输入输出
由图可知,数据流分为输入输出流,当然,Java函数库内相应的处理类也分为输入输出两种。除此之外,若以数据处理方式来分类,数据流还可以分为字节流(byte)和字符流(char)两种。
1.输入类:
(1)字节型:类名称大部分带有Stream,例如:FileInputStream
(2)字符型:类名称大部分带有Reader,例如:FileReader
2.输出类:
(1)字节型:类名称大部分带有Stream,例如:FileOutputStream
(2)字符型:类名称大部分带有Reader,例如:FileWriter
(提示:InputStreamReader类之所以同时带有Stream和Reader,是因为它可将位型流转换成字符型,所以可以所示这两种传输型的桥柳,OutputStreamWriter同理)

                                      Java流的主要结构:

类的结构
既然提到了流,属于Java.io包,这里就顺便把IO包下面的File类也顺便说了吧。File类专门提供文件管理功能,例如文件的查询,增加,修改和删除等功能。文件查询仅限于查询文件的基本信息,如文件名,文件大小,修改日期等。File类不能用来直接存取文件内容,若要直接存取内容,就必须用到流的相关函数。
下面是File类的相关函数:
1.构造函数

public File(String pathname)

(依据传入的pathname(路径名称)建立File对象,虽然建立了File对象, 但还未真正在硬盘上建立相应的文件或目录,必须调用createNewFile()或mkdirs()方法才能真正建立文件或目录)

public File(File parent,String child)

(依据传入的parent对象与child路径建立File对象。虽然建立了File对象, 但还未真正在硬盘上建立相应的文件或目录,必须调用createNewFile()或mkdirs()方法才能真正建立文件或目录)
2.方法

public boolean createNewFile()

(建立一个新的文件,成功返回true,失败传回false 异常事件—>当IO发生问题,会产生IOException)

public Boolean delete()

(可以删除文件或者目录(条件是目录必须为空)删除成功返回true,失败返回false)

public void deleteOnExit()

调用此方法的文件会在程序执行结束时自动删除,删除成功返回true,失败传回false

public boolean exists()

检查文件或者目录是否存在,存在返回true,不存在返回false

public String getName()

取得路径最后的名称,可能是文件或目录名称,例如:[E:/Books/book.txt],调用此方法会取得[book.txt]

public String getParent()

取得上一层的路径,例如:[E:/Books/book.txt],调用此方法会取得[E:/Books]

public String getPath()

取得完整路径的名称,例如:[E:/Books/book.txt],调用此方法会取得[E:/Books/book.txt]

public boolean isFile()

判断是否为文件,是的话返回true,否则返回false

public long lastModified()

传回最后修改时间

public long length()

传回文件的大小(单位为byte),如果是目录,则传回0

public boolean renameTo(File dest)

将原名称改为新名称(新名称就是dest对象代表的名称),成功返回true,失败返回false

public String[] list()

如Flile对象为目录,则返回该目录内的所有文件和目录的名称,如果是对象,则返回null

public File[] listFiles()

如果File对象为目录,传回该目录内的所有File对象,所以为File数组。如果File是我文件,则传回null

public boolean mkdir()

建立目录,如果上一层路径不存在,则无法建立。例如:路径为【E:/Books/book.txt】,如果【E:/Books】不存在,则无法建立book.txt目录

public boolean mkdirs()

建立目录,即使上一层路径不存在,也会自动建立所需目录。成功返回true,失败返回false

public boolean setReadOnly()

设定只读模式,成功返回true,失败返回false
代码举例:在E盘建立Book目录,然后在该目录下建立book1.txt,book2.txt

public class Test {
       public static void main(String[] args) throws IOException {
          File file=new File("E:/Books");
          if(!file.exists()){//假设目录不存在
          file.mkdirs();      //在E盘下面建立Books目录
       }
        File book1_file=new File(file,"book1.txt");
        if(!book1_file.exists()){
             book1_file.createNewFile(); //在Books目录下建立book1.txt文件
        }
        File book2_file=new File(file,"book2.txt");
        if(!book2_file.exists()){
             book2_file.createNewFile(); //在Books目录下建立book2.txt文件
        }
     String total_fileName[]=file.list();  //取得Books目录下的所有文件名字
     File total_file[]=file.listFiles();
        for(String s:total_fileName){
            System.out.println(s+"  ");

        }
        for(File f:total_file){
            Date date=new Date(f.lastModified());
            System.out.println(date+"  "+f.length()+"字节"); //打印文件最后修改时间和字节大小
        }       
       }
}

2.字节流(FileInputStream, FileOutputStream, BufferedInputStream, BufferedOutputStream)
举例:给上述的book1.txt写入数据

代码如下:

public class Test {
       public static void main(String[] args) throws IOException {
        File file=new File("E:/Books/book1.txt");
        OutputStream os=new FileOutputStream(file);//以字节流的方式写入文件
        //温馨提示:如果想要在文件内容后面追加的话,函数为OutputStream os=new FileOutputStream(file,true)
        String s="田浩兵是大帅哥,呸,真不要脸...";
        BufferedOutputStream bos=new  BufferedOutputStream(os);//提供一个缓冲区,以免一直与文件建立链接,效率低
        bos.write(s.getBytes());

        bos.close();//关闭流的顺序很重要!!!,先关闭缓冲区,然后再关闭输出流
        os.close();

       }
}

运行结果
接下里,我们从book1.txt中按照字节流的方式读出来试试:
代码如下:

public class Test {
       public static void main(String[] args) throws IOException {
        File file=new File("E:/Books/book1.txt");
        InputStream is=new FileInputStream(file);
        BufferedInputStream bis=new BufferedInputStream(is);//缓冲区
        int len;
        while((len=bis.read())!=-1){
            System.out.print((char)len);

        }
        bis.close(); // 关闭流,还是那句话,顺序很重要!!!
        is.close();
    }
}

输出结果:
这里写图片描述
(Fuck!!!,怎么是乱码?田浩兵大帅哥去哪里了呢?(害羞….))

原因解释:在文本中,中文占用两个字节,字符占用一个字节,因为我们是一个字节一个字节的读出来的,所以读到一个中文时,比如读到田,只能读田的一半,当转换为字符时,当然是乱码了。那怎么解决呢?

代码如下:

public class Test {
       public static void main(String[] args) throws IOException {
        File file=new File("E:/Books/book1.txt");
        InputStream is=new FileInputStream(file);
        BufferedInputStream bis=new BufferedInputStream(is);//缓冲区
        int len1,len2;
        while((len1=bis.read())!=-1){
                if(!(len1>=0&&len1<128)){ //通过ASCII来判断是否为中文
                    len2=bis.read(); 
               System.out.print(new String(new byte[]{(byte)len1,(byte)len2})); //将len1和len2拼接起来,组成一个byte数组,因为分别读了一半    
                }else{
                    System.out.print((char)len1);   //转换为字符输出
                }
        }
       bis.close(); //关闭流,还是那句话,顺序很重要!!!
       is.close();
       }
}

输出结果:
这里写图片描述
(这不,大帅哥又出来了…)

3.字符流(InputStreamReader , BufferReader, OutputStreamWriter , BufferedWriter)
我们往book1.txt追求一句话(田浩兵真的是大帅哥 )

代码如下:

public class Test {
       public static void main(String[] args) throws IOException {
        File file=new File("E:/Books/book1.txt");
        FileWriter fw=new FileWriter(file,true);//表示往文本后面追加,而不是覆盖   
        BufferedWriter bw=new BufferedWriter(fw);//以字符流的方式写入
        String name="田浩兵真的是大帅哥";
        bw.write(name);
        bw.close();
        fw.close();
       }
}

执行结果:
这里写图片描述
(田浩兵真的是大帅哥就出来了)
接下来,我们从这个文本以字符流的方式读出来试试:
代码如下:

public class Test {
       public static void main(String[] args) throws IOException {
        File file=new File("E:/Books/book1.txt");
        FileReader fw=new FileReader(file);     
        BufferedReader bw=new BufferedReader(fw);
        String s;
        while((s=bw.readLine())!=null){//以字符流的方式读文本,一次不仅仅读取一个字节,可以一行一行的读取
            System.out.print(s);
        }

        bw.close();
        fw.close();
       }
}

执行结果:
这里写图片描述
4.最后,还有两个函数,分别为InputStreamReader和OutputStreamWriterr,这两个函数是字节流转换为字符流的桥梁。我们下面来用代码讲解:

public class Test {
       public static void main(String[] args) throws IOException {
        File file=new File("E:/Books/book1.txt");
        OutputStream is=new FileOutputStream(file,true); 
        String name ="  字节流转换为字符流";

        is.write(name.getBytes());
        BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(is));//字节流转为字符流,然后增加一个缓冲区
        bw.close();
        is.close();

       }
}

运行结果:
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值