• java之IO处理


    File文件基础

    文件与文件夹抽象路径名称的表示。其构造方法有四个

    File(File parent,String child):从抽象父文件夹下创建一个File实例。

    File(String parent,String child):从父文件夹下创建一个File实例。

    File(String pathname):从指定路径下创建一个File实例。

    File(URI path):从URI转换成抽象路径下创建一个File实例。


    listFiles()方法:返回一个抽象路径名数组,这些抽象路径名表示文件夹中的子项(文件或文件夹)

    File file = new File("/home/colin");
    File[] childs = file.listFiles();

    listFiles(FileFilter filter):FileFilter是抽象路径名的过滤器。能够用于返回过滤器要求的子文件夹
    File file = new File("/home/colin");
    		//有没有考虑过,java中不同意实现接口实例,可是在匿名内部类中却实现了接口。比方这个FileFilter接口
    		//实际上假设查看编译后的代码(会发现编译后的代码中有一个class文件。这个class实现了这个接口。并重写了这个接口的方法)
    		//所以这是一种虚拟实例化接口。或者理解为间接实例化接口。
    		File[] childs = file.listFiles(new FileFilter() {			
    			@Override
    			public boolean accept(File pathname) {
    				return pathname.getName().startsWith(".");
    			}
    		});

    另一个listFiles(FilenameFileter filter):FilenameFile用于检測指定文件是否包括在特定文件夹下

    其它API相对简单了,获取文件状态、创建删除文件


    RandomAccessFile随机读写文件

    File 实例仅仅涉及到对文件的操作,java提供了能够对文件随机訪问的操作,訪问包含读和写操作。这样的实现是基于指针的操作。

    两个构造方法:

    RandomAccessFile(File name,String model)

    RandomAccessFile(String name,String model)

    model指定的是对文件随机訪问操作模式。有两种模式各自是仅仅读模式和读写模式。"r"表示文件的訪问是仅仅读的,"rw"表示读和写模式。


    RandomAccessFile file = new RandomAccessFile("/home/colin","rw");
    			

    写数据:

    write(byte[] b):将指定自己数组b写到随机读写文件里,写到指针的位置

    write(byte[] b,int off,int len):指定了起始位置和长度

    write(int n):将n的低八位写到文件里去

    他还有写入特定特性的方法:writeBoolean(boolean b)、writeInt(int n)、writeDouble(double v)、writeChart(chart c)、writeCharts(String s)、writeByte(int n)、writeBytes(String s)、writeFloat(Float t)等

    读数据:

    int read():读取1byte(8位)放到int的低八位中,高24为为0。假设读到-1,说明读到了文件的末尾

    int read(byte[] b):最多读取b.length个字节到数组中。返回值为实际读取到的字节量

    int read(byte[] b,int off, int length):指定读取数组的起始位置和读取长度

    对应的还有读取特定类型数据的read

    readBoolean()、readFloat()等等。特别另一个readLine()读取当前位置的一行

    这些都是从当前指针位置開始读取的

    释放关联的资源:void close()

    获取当前RandomAccessFile的指针:long getFilePoint(),以字节为单位。比方假设一个Int是4位

    移动当前指针位置:void seek(long pos)

    跳过n个字节:int sikpBytes(int n):返回跳过的实际字节数,n为负数不跳过不论什么字节

    RandomAccessFile file = null;
    		try {
    			file = new RandomAccessFile("/home/colin/test.txt","rw");
    			//byte[] b = "this is sample RandomAccessFile".getBytes();
    			//file.read(b);
    			byte[] b = new byte[10];
    			while(file.read(b) >0){
    				System.out.println(new String(b));
    				System.out.println(file.getFilePointer());		//获取文件指针
    				file.skipBytes(1);		//每次读取跳过一个字节
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}finally{
    			if(file != null)
    				file.close();
    		}


    基本IO

    输入是指从外界进入程序方向,即当我们须要读取数据的时候,使用输入。

    输出是指从程序发送到外界方向,通常我们须要写出数据到外界,所以输出是用来写数据的。

    流的分类

    依据单位:字节流(8bit,图片视频等)和字符流(16bit,文本)

    依据角色:节点流(直接作用在文本上的流。直接与特定的地方(磁盘、内存)相连)和处理流(在节点流外层的流。是对一个已经存在流的连接和封装,在所封装的流的功能上实现数据的读写)

    java中40多种流都是从4个基类派生出来的

                字节流               字符流

    输入:InputStream     Reader

    输出:OutputStream  Writer


    InputStream和OutputStream

    二者都是字节流的抽象基类。定义了主要的read和write方法,read()、read(byte[] a,int off,int length)、read(byte[] b)、write(int b)、write(byte[] b)、write(byte[] b,int off ,int len)

    Reader和Writer

    reader和writer都是字符流的抽象基类,定义了读取字符的read和write。read()、read(char[] cbuf)、read(char[] cbuf,int off, int len)、write(char c)、write(char[] cbuf)、cbuf(cbuf,int off ,int len)

    文件流

    文件字节流:

    FileOutputStream能够使用下面几种方法构造:

    FileOUtputStream(File file)     

    FileOutputStream(String name)

    指定写入的文件,假设该文件存在的化会清除该文件上面的内容
    FileOutputStream(File file,boolean append)

    FileOutputStream(String name,boolean append)

    假设指定append參数为true。则假设写入的文件存在。是以追加的方式进行写入的

    FileInputStream能够使用下面方法构造:

    FileInputStream(File file)

    FileOutputStream(String name)

    文件字节流实现了inputStream和outputStream的基本read和write

    注意假设读取的时候返回-1,则说明读取到了EOF


    利用文件流实现文件的复制:

    		
    		File file1 = new File("/home/colin/hello.py");
    		File file2 = new File("/home/colin/hello2.py");
    	
    		FileInputStream input = null;
    		FileOutputStream output = null;
    		try {
    			input = new FileInputStream(file1);
    			output = new FileOutputStream(file2);
    			byte[] b = new byte[10];
    			int len = -1;
    			while((len=input.read(b))!=-1){
    				output.write(b, 0, len);
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			try {
                                   //先关输入流。再关输出流
                                     if(inputput != null)
    					inputput.close();
    				if(output != null)
    					output.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    		
    	

    FileReader和FileWriter与FileInputStream和FileOutputStream使用情况一样。

    缓冲流

    BufferedInputStream原理:缓冲字节输入流,内部维护一个缓冲区。该流会尽可能一次性读取若干字节到缓冲区。然后逐一返回知道缓冲区中的数据被所有读取完成,从而降低读取次数,提高读取效率,BIS就是一个处理流,该流提供了缓冲功能。他还提供了mark、reset和skip方法

    提供的构造方法:

    BufferedInputStream(InputStream input)

    BufferedInputStream(InputStream input,int size):size指定缓冲区大小


    BufferedOutputStream原理:缓冲输出流。内部维护一个缓冲区,每当向该流写入数据的时候,都会现将数据存储缓冲区中,当缓冲区已满的时候,缓冲流会将数据一次性所有写出。

    提供的构造方法:

    BufferedOutputStream(OutputStream out)

    BufferedOutputStream(OutputStream out,int size):指定缓冲区大小

    BufferedOutputStream仅仅提供了write和flush()方法。flush()清空缓冲区,将缓冲区中的数据强制写入。


    利用缓冲流实现文件复制:

    		BufferedInputStream bis = null;
    		BufferedOutputStream bos = null;
    		try {
    			bis = new BufferedInputStream(new FileInputStream(new File("/home/colin/hello.py")));
    			bos = new BufferedOutputStream(new FileOutputStream(new File("/home/colin/hello3.py")));
    			int len = -1;
    			byte[] b = new byte[10];
    			while((len=bis.read(b)) !=-1){
    				bos.write(b, 0, len);
    			}
    			bos.flush();
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}finally{
    			try {
    				//先关输入流,再关输出流
    				if(bis != null)
    					bis.close();
    				if(bos != null)
    					bos.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    			
    		}
    	

    BufferedReader和BufferedWriter与BufferedInputStream和BufferedOutputStream实现原理是一样的,可是BufferedWriter提供了newLine(),写入换行符的方法

    对象流

    对象序列化:对象存在内存中,有时候须要将对象保存到磁盘上。或者将对象进行传输等这种操作。

    这时候须要将对象转化为一个字节序列,这个过程称为对象序列化。

    对象反序列化:有时候须要将字节序列转化成为相应的对象。这个过程成为对象的反序列化。

    ObjectOutputStream:用来将对象进行序列化的输出流

    提供的构造方法:

    ObjectOutputStream()

    ObjectOutputStream(OutputStream out)

    使用其write方法,将对象转化成为一个字节序列后写出,write方法提供了诸如writeInt()等此类方法。

    ObjectInputStream:用来将对象反序列化

    提供的构造方法:

    ObjectInputstream()

    ObjectInputStream(InputStream input)

    使用其提供的readObject()方法,读取字节并转化为相应的对象


    这个总体思路是要对对象进行传递。须要将对象转换成为字节流以便传输,所以首先通过ObjectOutputStream进行写入。将对象写成字节进行传输。传递到目标位置后须要读取,这时候将传输的字节转换成为对象。

    假设使用ObjectOutputStream进行序列化写入,须要序列化对象实现Serializable接口,该接口并没有不论什么方法仅仅是序列化标志。通常实现该接口须要给出一个serialVersionUID,表明该类版本号,若不显示声明编译器也会经过计算给出一个serialVersionUID。可是不同编译器实现有所不同。所以假设想要跨平台,都应该显示声明版本号号。当类的对象序列化到磁盘上面,之后随之需求改变。改变了类的属性,那么反序列化就会出现InvalidClassException,这样就会造成不兼容问题。

    但当serialVersionUID同样时。会将不一样的Field以type的预设值反序列化,能够避开不兼容问题

    transient关键词:当我们对对对象进行序列化后,得带的字节序列往往比較大。有时我们在对一个对象进行序列化时能够忽略某些不必要的属性,从而对序列化后得到的字节序列瘦身,能够将其声明为transient,这样这些属性在序列化时会被忽略。

    实例:

    /*
     *构造Emp类,对其对象进行序列化与反序列化
     */
    public class Emp implements Serializable {
    
    	private static final long serialVersionUID = 1L;
    	private String name;
    	private int age;
    	private double salary;
    	private transient String description;    //使用transient修饰。在反序列化时输出null
    	 
    	public Emp(String name,int age,double salary,String description){
    		this.name = name;
    		this.age = age;
    		this.salary = salary;
    		this.description = description;
    		}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public double getSalary() {
    		return salary;
    	}
    	public void setSalary(double salary) {
    		this.salary = salary;
    	}
    	public String getDescription() {
    		return description;
    	}
    	public void setDescription(String description) {
    		this.description = description;
    	}
    	
    	@Override
    	public String toString() {
    		return "Emp [name="+name+",age="+age+",salary="+salary+",description="+description+"]";
    	}
    }
    
    
    
    /*
         * 将Emp对象序列化。而且存储
         */
        public static  void testOos(){
            ObjectOutputStream oos = null;
            try {
                FileOutputStream fos = new FileOutputStream(new File("/home/colin/oos.obj"));
                oos = new ObjectOutputStream(fos);
                Emp emp = new Emp("colin", 23, 13000, "I want you!!!");
                oos.writeObject(emp);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(oos != null)
                        oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
        /*
         * 将存储的Emp对象反序列输出
         */
        public static void testOis(){
            ObjectInputStream ois = null;
            try {
                FileInputStream fis = new FileInputStream(new File("/home/colin/oos.obj"));
                ois = new ObjectInputStream(fis);
                Emp emp = (Emp)ois.readObject();
                System.out.println(emp.getName()+","+emp.getAge()+","+emp.getSalary()+","+emp.getDescription());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    



  • 相关阅读:
    webpack4.0--安装操作
    刮刮卡制作思路--canvas
    Webpack 基础了解
    音量控制条demo,拖拽定位,点击定位
    我收到过的最好的职场建议——Nicholas C. Zakas
    跨域通信--Window.postMessage()
    小球沿贝塞尔二阶曲线的运动
    ES6 简写方式
    React 基础编写
    数据结构(十三)— 树结构之二叉树
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/6933161.html
Copyright © 2020-2023  润新知