zoukankan      html  css  js  c++  java
  • Java IO


    IO类

    IO本身就是输入输出的意思,IO类就是为了与磁盘进行IO相关操作的工具、桥梁;

    Java IO

    IO类基本可以分成字节流字符流
    而既然是IO,那不管是哪个流都是分为输入和输出两大块


    字节流

    字节流

    InputStream(抽象)(字节输入流)

    InputStream是所有字节输入流的抽象基类,提供字节输入的通用方法

    基本方法:

    read() //从文件中读取数据的下一字节
    read(byte[]) //从文件中读取一个数组量的字节
    read(byte[], int, int) //从文件中读取限定位置数量的字节
    

    注:当读取不到字节时会返回 -1


    FileInputStream

    该流是父类提供用于实例化的读取文件的输入流,能从指定文件中读取字节,从而读取文件内容

    构造方法有两个:

    1. 需要实例化一个File文件对象
      • FileInputStream( File )
    2. 不用实例化File对象
      • FileInputStream( String )

    使用方式

    1. 一个一个字节读取(效率慢)
    public static void main(String[] args) throws IOException {
        //创建一个字节输入流对象,必须明确数据源
        File file = new File("c:\file.txt");
        FileInputStream fis = new FileInputStream(file);
        
        //使用 read()一次读一个字节。
        int ch = 0;
        while((ch=fis.read())!=-1){
            System.out.println("ch="+(char)ch);		
        }
        fis.close();
    }
    
    1. 一组一组数组读取
    public static void main(String[] args) throws IOException {
        // 创建一个字节输入流对象,必须明确数据源
        File file = new File("c:\file.txt");
        FileInputStream fis = new FileInputStream(file);
        
        // 创建一个字节数组。
        byte[] buf = new byte[1024];//长度可以定义成1024的整数倍。		
        int len = 0;
        while((len=fis.read(buf))!=-1){
            System.out.println(new String(buf,0,len));
        }
        fis.close();
    }
    

    BufferedInputStream(字节缓冲输入流)

    这是FilterInputStream的子类,它除了父类功能之外还提供了 “缓冲”“mark标记”“重置” 等功能方法

    构造方法:

    1. BufferedInputStream( FileInputStream )

    使用方法

    		FileInputStream fileIn = new FileInputStream("abc.txt");
    		//1, 把基本的流包装成高效的流
    		BufferedInputStream in = new BufferedInputStream(fileIn);
    		//2,读数据
    		int ch = -1;
    		while ( (ch = in.read()) != -1 ) {
                System.out.print((char)ch);
    		}
    		in.close();
    

    OutputStream(抽象)(字节输出流)

    OutputStream是所有字节输出流的抽象基类,提供内存字节输出到文件的通用方法

    基本方法:

    write(int) //将指定字节写入输出流
    write(byte[]) //将一定数量字节从数组写入输出流
    write(byte[], int, int) //将指定数组指定位置数量写入输出流
    

    注:如果文件不存在,则会创建该文件,如果存在,则覆盖


    FileOutputStream

    该流是父类提供用于实例化的文件数据输出流,能将内存数据写入磁盘文件上

    构造方法有四个:

    1. 需要实例化一个File文件对象
      • FileOutputStream( File )
      • FileOutputStream( Fileboolean )
    2. 不用实例化File对象
      • FileOutputStream( String )
      • FileOutputStream( String , boolean )

    这里boolean代表如果有同名文件,是否在文件内容末位继续添加写入内容(不覆盖)

    使用方式

    public static void main(String[] args) throws IOException {
        //创建存储数据的文件。
        File file = new File("c:\file.txt");
        //创建一个用于操作文件的字节输出流对象。一创建就必须明确数据存储目的地。
        FileOutputStream fos = new FileOutputStream(file ,true);
        String str = "
    "+"HelloIO";
        //调用父类中的write方法。
        fos.write(str.getBytes());
        //关闭流资源。
        fos.close();
    }
    

    BufferedOutputStream(字节缓冲输出流)

    这是FilterInputStream的子类,它除了父类功能之外还提供了 “缓冲” 等功能方法

    构造方法:

    1. BufferedOutputStream( FileOutputStream )

    使用方法

    	//创建基本的字节输出流
    	FileOutputStream fileOut = new FileOutputStream("abc.txt");
    	//使用高效的流,把基本的流进行封装,实现速度的提升
    	BufferedOutputStream out = new BufferedOutputStream(fileOut);
    	//2,写数据
    	out.write("hello".getBytes());
    	//3,关闭流
    	out.close();
    

    练习
    1. 使用字节流复制文件
    public static void main(String[] args) throws IOException {
        File srcFile = new File("c:\YesDir	est.JPG");
        File destFile = new File("copyTest.JPG");
        // 明确字节流 输入流和源相关联,输出流和目的关联。
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        //定义一个缓冲区。
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = fis.read(buf)) != -1) {
            fos.write(buf, 0, len);// 将数组中的指定长度的数据写入到输出流中。
        }
        fos.close();
        fis.close();
    }
    
    1. 使用缓冲流复制文件(效率更快)
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new FileReader("D:/Plan.txt"));
        BufferedWriter ou = new BufferedWriter(new FileWriter("C:/Plan.txt"));
    	
        String line = null;
        while( ( line = in.readLine() ) != null) {
    	ou.write(line);
    	ou.newLine();
        }
        ou.close();
        in.close();
    }
    


    字符流

    字符流

    Reader(抽象)(字符输入流)

    Reader是所有字符输入流的抽象基类,把输入流中的字符读到内存中

    基本方法:

    read() //从文件中读取下一字符
    read(char[]) //从文件中读取一定数量字符到数组中
    

    注:当读取不到字符会返回 -1


    BufferedReader

    该流能缓冲各个字符,从而提供字符、数组、字符串的高效读取

    构造方法:

    1. 需要实例化一个File文件对象
      • BufferedReader( FileReader )

    使用方式

    常用特性方法:

    • readLine() ——没有则返回 null
        BufferedReader in = new BufferedReader(new FileReader("file.txt"));
    
        String line = null;
        while( (line = in.readLine()) != null ){
            System.out.println(line);
        }
        in.close();
    

    InputStreamReader(输入转换流)

    使用指定编码表,将输入的“字节”转换成“字符”的输入流

    使用方法

    public static void readC() throws IOException{
        //创建读取文件的字节流对象
        InputStream in = new FileInputStream("c:\c.txt");
        
        //创建转换流对象 
        //这样创建对象,会用本地默认码表读取,将会发生错误解码的错误
        //InputStreamReader isr = new InputStreamReader(in);
        InputStreamReader isr = new InputStreamReader(in,"utf-8");
        
        //使用转换流去读字节流中的字节
        int ch = 0;
        while((ch = isr.read())!=-1){
        	System.out.println((char)ch);
        }
        isr.close();
    }
    

    注意:一旦要指定其他编码时,绝对不能用子类(FileReader),必须用该转换流

    其实在FileReader使用的时候:

        FileReader fr = new FileReader("a.txt");
    

    这里就使用的是默认编码表


    FileReader

    这个类就是上面所说的简化而来的子类,能方便快捷地读取文件字符

    构造方法:

    1. 需要实例化一个File文件对象
      • FileReader( File )
    2. 无需手动实例化File文件对象
      • FileReader( String )

    使用方式

    public static void readText() throws IOException {
        FileReader fr = new FileReader("E:\test\a.txt");
        int ch = 0;
        while((ch = fr.read())!=-1){
            //输出的字符对应的编码值
            System.out.println(ch);
            //输出字符本身
            System.out.println((char)ch);
        }
    }
    

    Writer(抽象)(字符输出流)

    OutputStream是所有字符输出流的抽象基类,提供内存字符输出到文件的通用方法

    基本方法:

    write( int ) //将单个字符写入输出流
    write( char[] ) //将一定数量字符数组写入输出流
    write( char[] , int , int ) //将指定数组指定位置数量写入输出流
    write( String ) //将字符串写入输出流
    write( String , int , int) //将字符串一部分写入输出流
    

    注:如果文件不存在,则会创建该文件,如果存在,则覆盖


    BufferedWriter

    缓冲各个字符,从而提供字符、数组、字符串的高效读取

    构造方法:

    • BufferedWriter( FileWriter )

    使用方式
    常用特性方法:

    • readLine() ——没有则返回 null
        FileWriter fileOut = new FileWriter("file.txt");
        BufferedWriter out = new BufferedWriter(fileOut);
        for (int i=0; i<5; i++) {
            out.write("hello");
            out.newLine();
        }
        out.close();
    

    OutputStreamWriter(输出转换流)

    使用指定编码表,将“字符”转换成“字节”的输出流,再使用字节流写出去

    public static void writeC() throws Exception {
        //创建与文件关联的字节输出流对象
        FileOutputStream fos = new FileOutputStream("c:\c.txt");
        //创建可以把字符转成字节的转换流对象,并指定编码
        OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
        //调用转换流,把文字写出去,其实是写到转换流的缓冲区中
        osw.write("你好");//写入缓冲区。
        osw.close();
    }
    

    注:当调用 write 方法时,流会将字符在码表进行查询,转成字节后存到缓冲区中


    FileWriter

    功能性同FileReader相似,是简化父类操作的字符输出流,方便地将字符写到文件中

    构造方法有四个:

    1. 需要实例化一个File文件对象
      • FileWriter( File )
      • FileWriter( Fileboolean )
    2. 无需手动实例化File文件对象
      • FileWriter( String )
      • FileWriter( String , boolean )

    boolean代表是否在文件末位继续添加(不覆盖)

    使用方法

    public static void main(String[] args) throws IOException {
        //演示FileWriter 用于操作文件的便捷类。
        FileWriter fw = new FileWriter("E:\text\fw.txt");
        fw.write("你好谢谢再见");//这些文字都要先编码。都写入到了流的缓冲区中。
        fw.flush();//刷新
        fw.close();// 关闭之前需要刷新它
    }
    

    注意:在写入字符的时候,需要先进行流的刷新,再关闭流


    练习
    1. 使用字符流复制文本文件
    public static void copyTextFile() throws IOException {
    	//1,明确源和目的。
    	FileReader fr = new FileReader("c:\a.txt");
    	FileWriter fw = new FileWriter("c:\copy.txt");
    	//2,为了提高效率。自定义缓冲区数组。字符数组。
    	char[] buf = new char[1024];
    	int len = 0;
    	while((len=fr.read(buf))!=-1){
                fw.write(buf,0,len);
    	}
    	//3,关闭资源。
    	fw.close();
    	fr.close();
    }
    
    1. 使用缓冲流复制文件(效率更快)
    public static void main(String[] args) throws IOException {
    	//1,指定数据源, 是数据源中读数据,采用输入流
    	BufferedReader in = new BufferedReader(new FileReader("file.txt"));
    	//2,指定目的地,是把数据写入目的地,采用输出流
    	BufferedWriter out = new BufferedWriter(new FileWriter("copy.txt"));
    	//3,读数据
    	String line = null;
    	while ( (line = in.readLine()) != null ) {
    		//4,写数据
    		out.write(line);
    		//写入换行符号
    		out.newLine();
    	}
    	//5,关闭流
    	out.close();
    	in.close();
    }
    


    还有一些常用IO

    由于想偷懒,就直接总结了

    Properties集合

    • 表示的是一个持久的属性集
    • 属性列表是个键值对
    • 每个键及其对应值都是一个String
    • 哈希表的子类map集合 中的方法都可以使用
    • 键值对可以存储到集合中,也可以存到持久化设备中
    基本方法
    setProperty( String , String ) //设置键值对到集合中
    getProperty( String ) //从键值对中根据指定的键获取值
    

    与流技术相结合的方法:

    load( InputStream ) //从输入流中读取属性键值对
    load( Reader ) //按行的格式从字符流中读取属性键值对
    store( OutputStream , String ) //以字节输出方法格式,将属性键值对写入输出流
    store( Writer , String ) //以字符输出方法格式,将属性键值对写入输出流
    

    (第二个参数String是写入文件中附带的注释)

    使用方式

    将集合中的内容存储到文件中:

    public static void main(String[] args) throws IOException {
    	//1,创建Properties集合
    	Properties prop = new Properties();
    	//2,添加元素到集合
    	prop.setProperty("周迅", "张学友");
    	prop.setProperty("李小璐", "贾乃亮");
    	prop.setProperty("杨幂", "刘恺威");
    	
    	//3,创建流
    	FileWriter out = new FileWriter("prop.properties");
    	//4,把集合中的数据存储到流所对应的文件中
    	prop.store(out, "save data");
    	//5,关闭流
    	out.close();
    }
    

    将文件中的数据读取到集合中:

    public static void main(String[] args) throws IOException {
    	//1,创建集合
    	Properties prop = new Properties();
    	//2,创建流对象
    	FileInputStream in = new FileInputStream("prop.properties");
        	//FileReader in = new FileReader("prop.properties");
    	//3,把流所对应文件中的数据 读取到集合中
    	prop.load(in);
    	//4,关闭流
    	in.close();
    	//5,显示集合中的数据
    	System.out.println(prop);
    }
    

    反序列化流

    • 反序列化的对象必须要提供该对象的字节码文件
    • 序列化接口声明的序列UID号不一致会报错
    ObjectInputStream(反序列化)

    对以前序列化的对象从流中进行读取

    构造方法:

    • ObjectInputStream( InputStream )

    基本方法:

    • readObject( ) ——从反序列化流中读取对象
    使用方式:
    public static void readObj() throws IOException, ClassNotFoundException {
        //1,定义流对象关联存储了对象文件
        FileInputStream fis = new FileInputStream("tempfile\obj.object");
        //2,建立用于读取对象的功能对象
        ObjectInputStream ois = new ObjectInputStream(fis);
        Person obj = (Person)ois.readObject();
    
        System.out.println(obj.toString());
    }
    

    序列化流

    • 这是专门用于操作对象的流,将对象存储到磁盘、网络中
    • JavaBean对象都需要做序列化
    ObjectOutputStream(序列化)

    将对象基本数据类型和图形写入字节输出流

    构造方法:

    • ObjectOutputStream( OutputStream )

    基本方法:

    • writerObject( Object ) ——写入指定对象
    使用方式:
    public static void writeObj() throws IOException {
        //1,明确存储对象的文件
        FileOutputStream fos = new FileOutputStream("tempfile\obj.object");
        //2,给操作文件对象加入写入对象功能
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        //3,调用了写入对象的方法
        oos.writeObject(new Person("wangcai",20));
        //关闭资源
        oos.close();
    }
    

    打印流

    输出信息最方便的类,能打印各种数据值

    构造方法:

    字节打印流 字符打印流
    PrintStream( File ) PrintWriter( File )
    PrintStream( OutputStream ) PrintWriter( OutputStream )
    PrintStream( OutputStream , boolean ) PrintWriter( OutputStream , boolean )

    基本方法:

    print( ) //此方法被重载多次,输出任意数据
    println( ) //输出任意数据后换行
    printf( ) //根据本地环境格式化输出
    

    注:

    System.out.println();
    
    //其实等价于
    PrintStream ps = new PrintWriter(System.out);
    ps.println();
    
    使用方式:
    public static void main(String[] args) throws IOException {
        //创建流
        //PrintWriter out = new PrintWriter("printFile.txt");//无自动刷新
        PrintWriter out = new PrintWriter(new FileWriter("printFile.txt"), true);
    
        //2,写数据
        for (int i=0; i<5; i++) {
            out.println("helloWorld");
        }
        //3,关闭流
        out.close();
    }
    

    NIO(管道流)

    • 管道流主要由 缓冲区(Buffer)管道(Channel) 两部分组成
    • 数据必须先读入缓冲区再进行处理
    NIO 与 普通IO的区别:
    1. NIO面向缓冲;IO面向流
    2. NIO是非阻塞的;IO是阻塞IO
    3. NIO有其选择器
    使用方式
    public static void main(String[] args) throws Exception {
        File file = new File("E:\work\TestFile\s.avi");
        FileInputStream fis = new FileInputStream(file);
    	
        FileOutputStream fos = new FileOutputStream("E:\work\TestFile\ss.avi");
        // 用字节流获取文件通道
        FileChannel in = fis.getChannel();
        FileChannel ot = fos.getChannel();
        	
        // 分配一个新的字节缓冲区,内容放在缓冲区里面,不能大也不能小
        ByteBuffer allocate = ByteBuffer.allocate((int)file.length());
        	
        // 读缓冲区的内容
        in.read(allocate);
        	
        // 查看指针的位置
        System.out.println(allocate.position());
        // 把指针设置为0
        allocate.flip();
        // 写缓冲区的内容到指定的位置
        ot.write(allocate);
        
        in.close();
        ot.close();
        fis.close();
        fos.close();
    }
    

    随机流

    • 该随机访问文件流可以在文件任意地方写入数据任意地方读取字节
    构造方法
    1. 需要实例化一个File文件对象
      • RandomAccessFile( File , String )
    2. 无需手动实例化File文件对象
      • RandomAccessFile( String , String )

    第二个String参数是mode,指定打开文件的访问模式

    • " r " :只读
    • " rw ":读写
    • " rws ":数据会立即写入文件,以防异常
    • " rwd ":已被write的数据会保存到文件

    随机流适合用于分文件复制断点网络下载


    使用IO进行网络下载

    public static void main(String[] args) throws Exception {
    	// 目的地
    	File savefile = new File("F:/fileTest/b.jpg");
    	String src = "http://tupian.aladd.net/2013/11/738.jpg";
    	long filelength = 0;
    	if(savefile.exists()){
    		filelength = savefile.length();
    	}
    	else{
    		filelength=0;
    	}
    	//创建url对象
    	URL url = new URL(src);
    	//建立远程连接
    	URLConnection connection= url.openConnection();
    	//建立Http请求的连接
    	HttpURLConnection hc = (HttpURLConnection) connection;
    	//设置请求消息
    	hc.setRequestProperty("Range", "bytes="+filelength+"-");
    	//读
    	InputStream is= hc.getInputStream();
    	BufferedInputStream bis = new BufferedInputStream(is);
    	//写
    	FileOutputStream bos = new FileOutputStream(savefile,true);
    	byte buff[] = new byte[1024*8];
    	int i ;
    	while((i=bis.read(buff))!=-1){
    		bos.write(buff,0,i);
    	}
    	bis.close();
    	bos.close();
    }
    


  • 相关阅读:
    Google搜索引擎如何运作:不会手动调整结果
    一个Ruby脚本
    IE灭绝!?
    除Windows之外的其他操作系统
    刚收到的新书
    奇怪的计算机语言
    小巧的menuetOS
    Ruby学习笔记(1)
    一个通知
    总结 asp.net 和 javascript获取本地IP(MAC)和服务器IP(MAC)的方法
  • 原文地址:https://www.cnblogs.com/zohnn/p/11409139.html
Copyright © 2011-2022 走看看