JavaSE——File I/O

一、使用File类操作文件或目录属性

1、创建一个File对象的语法格式:

      File file=new File(String pathName);

      例如:

      File file=new File("C:/test.txt");

      可以用 ‘ / ’ 或者 ‘ \\ ’;

2、File类的常用方法:

package I_O;

import java.io.File;
import java.io.IOException;

public class Test {

	public static void main(String[] args) {
		File file = new File("E:/test.txt");

		if (file.exists()) {
			if (file.isFile()) {
				System.out.println("文件名称:" + file.getName());
				System.out.println("相对路径:" + file.getPath());
				System.out.println("绝对路径:" + file.getAbsolutePath());
				System.out.println("文件大小:" + file.length() + "字节");
			}
			if (file.isDirectory()) {
				System.out.println("这是一个目录!");
			}
		} else {
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println("文件不存在,现已创建!");
		}
	   /**
		 * 文件存在时输出: 
		 * 文件名称:test.txt 
		 * 相对路径:E:\test.txt 
		 * 绝对路径:E:\test.txt 
		 * 文件大小:0字节 
		 * 
		 * 文件不存在时输出:
		 * 文件不存在,现已创建!
		 * 已删除!
		 */
	}

}

      首先,外层先判断文件或者目录是否存在,如果存在,则判断是文件还是目录,如果是文件,则用相应的方法输出文件的各项信息,如果文件或路径不存在,则在指定的路径下创建一个指定名称的文件,之后再把它删除;

      注意:在创建、删除、操作文件各项属性之前,必须先判断文件是否存在,否则可能会出现错误!

二、java的流

1、流是指一串流动的字符,是以先进先出的方式发送和接受数据,这里要与栈进行区分,栈是先进后出;

2、一个流是一个输入设备或输出设备的抽象表示;

3、流对象构造的时候往往会和数据源联系起来,数据源分为源数据源和目标数据源;

4、流具有明确的方向性,当向一个流写入数据时,这个流联系的是目标数据源,这个流被称为输出流,当从一个流中读取数据时,这个流联系的是源数据源,这个流被称为输入流;

三、流的分类

1、按照流向进行划分,可以分为输入流和输出流:

 

 2、按照所操作的数据单元的不同,可以分为字节流和字符流:

注意:

      字节流操作的最小数据单元为8位的字节,而字符流操作的最小数据单元是16位的字符;

      字节流建议用于二进制的数据,字符流用于文本,他们的用法几乎一模一样;

3、以上四个基类都是抽象类,只能用做实现具体的输入或输出功能子类的基类;

四、使用字节流读取文本文件

1、InputStream读取数据的常用方法:

     int read( ):读取一个8位的字节;

     int read(byte[ ] b):将数据读取到字节数组中;

     int read(byte[ ] b,int off,int len):从输入流中读取len长度的字节,保存到字节数组b中,保存位置从下标off开始;

     void close( ):关闭输入流;

     int available( ):返回输入流读取的估计字节数;

2、在实际应用中,我们通常使用InputStream的子类FileInputStream类来实现文本文件内容的读取,常用的构造方法有以下两个:

     (1)、FileInputStream(File file)

          File file=new File( " C:/test.txt " );

          InputStream input=new FileInputStream(file);

     (2)、FileInputStream(String pathName)

          InputStream input=new FileInputStream( " C:/test.txt " );

package I_O;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Test {

	public static void main(String[] args) {
		// 创建一个字节输入流对象
		FileInputStream input = null;
		try {
			// 将字节输入流对象指向源数据源
			input = new FileInputStream("E:/test.txt");
			// 声明变量接收读取到的内容(因为这里是读取一个8位的字节,转换为0~255的整数,所以用int来接收)
			int data;
			System.out.println("可读取的字节数:" + input.available());
			System.out.println("内容如下:");
			// 循环读取源数据源内容并在控制台输出
			while ((data = input.read()) != -1) {
				System.out.print((char) data + "");
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (input != null)
					input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

五、使用字节流写文本文件

1、OutputStream类的作用是将内存中的数据输出到文件中,常用方法如下:

      void write( int c ):写入一字节数据;

      void write( byte[ ] c ):将字符数组c中的所有字节输出到输出流中;

      void write( byte[ ] c,int off, int len):从字节数组的off下标开始,长度位len的字节数据输出到输出流中;

      void close( ):关闭输出流;

2、在实际应用中,我们通常使用OutputStream的子类FileOutputStream类来实现向文本文件写入数据,常用的构造方法有以下三个:

      (1)、FileOutputStream( File file )

            File file=new File( "C:/test.txt" );

            FileOutputStream ouput=new FileOutputStream( file );

      (2)、FileOutputStream( String pathName )

            FileOutputStream ouput=new FileOutputStream( "C:/test.txt" );

      (3)、FileOutputStream( String pathName,boolean append),append表示是否在文件末尾添加数据,若设置位true,则在文件末尾添加数据,若设置为false,则覆盖原文件内容;

            FileOutputStream ouput=new FileOutputStream( "C:/test.txt",true);

      注意:第一种和第二种构造方法在向文件写入数据时,会覆盖原文件内容,如果指定路径下的文件不存在,则会创建该名称的空文件,只在再写入数据,如果指定的文件路径存在,但是代表一个文件目录,则此时会抛出FileNotFoundException;

package I_O;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {

	public static void main(String[] args) {
		//创建一个字节输出流对象
		FileOutputStream output=null;
		try {
			//将字节输出流对象指向文件,并设置在文件末尾追加数据
			output=new FileOutputStream("E:/test2.txt",true);
			//创建要写入文件的字符串,并设置位输入完后换行
			String str="这个夏天真的很热啊!"+"\r\n";
			byte[] c=str.getBytes();
			//使用write方法将数据写入文件,从字符数组c的下标位0处开始,到c.length结束
			output.write(c, 0, c.length);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(output!=null)
				output.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

六、使用字符流读取文件中的数据

1、Read类是读取字符类的抽象类,常用方法如下:

      int read( ):从输入流中读取单个字符;

      int read( byte[ ] c ):从输入流中读取c.length长度的字符,保存到字符数组c中,返回实际读取的字符数;

      int read( char[ ] c,int off,int len ):从输入流中读取len长度的字节,保存到字节数组c中,保存位置从下标off开始;

      void close( ):关闭流;

2、在实际应用中,通常使用Read类的子类FileReader,常用的构造方法如下:  

      (1)、FileReader( String pathName )

            Reader input=new FileReader( "C:/test.txt" );

3、FileReader通常与Reader类的子类,BufferedReader结合使用,BufferedReader是带有缓冲区的,他可以先把一些数据读到缓冲区,接下来的操作都是从缓冲区内获取数据,避免每次都从数据源读取数据进行字符编码的转换,从而提高程序的读取操作效率,常用的过后早方法如下:

      (1)、BufferedReader( Reader in );

            Reader input=new FileReader( "C:/test.txt" );

            BufferedReader br=new BufferedReader( input );

package I_O;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Test {

	public static void main(String[] args) {
		// 声明Reader对象和BufferedReader对象
		Reader input = null;
		BufferedReader br = null;

		try {
			// 指向对象
			input = new FileReader("E:/test.txt");
			br = new BufferedReader(input);
			// 读取第一行,之后进入循环读取,在控制台输出读取的上一行之后,继续读取下一行,直到line=null为止
			String line = br.readLine();
			while (line != null) {
				System.out.println(line);
				line = br.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (br != null)
					br.close();
				if (input != null)
					input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

七、使用字符流写文本文件

1、用字符流向目标数据源中写入数据时,用到的是Writer类,常用的方法如下:

      writer( String str ):将字符串str中的内容输出到指定的输出流或文件中;

      writer( String str,int off,int len ):将字符串str中的内容输出到指定的输出流或文件中,从str的下标off开始,长度位len;

      void close(  ):关闭输出流;

      void flush(  ):刷新输出流;

2、FileWriter类是Writer类的子类,常用的构造方法如下:

      (1)、FileWriter( String fileName );

            Writer ouput=new FileWriter( "C:/test.txt" );

3、实际开发中,我们通常与Writer类的子类BufferedWriter类结合使用,以提高效率,同样的,BufferedWriter也是带有缓冲区的,是先把一批数据写入缓冲区,当缓冲区写满的时候,再把缓冲区的数据写到字符输出流中,这样可以避免每次都执行物理写操作,从而提升效率,常用的构造方法如下:

      (1)、BufferedWriter( Writer output );

            Writer fw=new FileWriter( "C:/test.txt" );

            BufferedWriter bw=new BufferedWriter( fw );

package I_O;

import java.io.*;

/**
 * @author 叶孤城 
 * 以下代码从E盘指定文件中读取内容,写入到C盘指定文件中,并在控制台输出
 */
public class Test {

	public static void main(String[] args) {
		// 将输入流对象与输出流对象开启
		Reader input = null;
		BufferedReader br = null;
		Writer output = null;
		BufferedWriter bw = null;

		try {

			input = new FileReader("E:/test.txt");
			br = new BufferedReader(input);
			output = new FileWriter("C:/test.txt", true);
			bw = new BufferedWriter(output);
			/*
			 * 将读取到的内容写入到指定位置的文件中 
			 * write方法是执行写入操作 
			 * newLine方法是在写完一行后执行换行操作 
			 * flush方法是清空缓存区内的内容
			 */
			String line = br.readLine();
			while (line != null) {
				System.out.println(line);
				bw.write(line);
				bw.newLine();
				bw.flush();
				line = br.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (bw != null) {
					bw.newLine();
					bw.close();
				}
				if (output != null)
					output.close();
				if (br != null)
					br.close();
				if (input != null)
					input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

八、二进制文件的读取

1、DataInputStrean类是FileInputStream的子类,利用它能读取二进制文件,构造方法如下:

      (1)、FileInputStream input=new FileInputStream( "C:/test.class" );

              DataInputStream dis=new DataInputStream( input );

九、二进制文件的写入

1、DataOutputStream类是FileOutputStream的子类,构造方法如下:

      (1)、FileOutputStream output=new FileOutputStream( "C:/test.class" );

              DataOutputStream dos=new DataOutputStream( output );

package I_O;

import java.io.*;

public class Test {

	public static void main(String[] args) {
		//声明二进制读取和写入对象
		DataInputStream dis = null;
		DataOutputStream dos = null;

		try {
			//创建一个输入流对象,可以把此处的class文件换成图片等其他类型
			FileInputStream input = new FileInputStream("E:/Test.class");
			dis = new DataInputStream(input);
			//创建一个输出流对象
			FileOutputStream output = new FileOutputStream("C:/Test.class");
			dos = new DataOutputStream(output);
			//定义读取内容的接收变量
			int temp;
			//循环读取和写入
			while ((temp = dis.read()) != -1) {
				dos.write(temp);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (dos != null)
					dos.close();
				if (dis != null)
					dis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

十、序列化与反序列化

1、序列化的目的就是实现对象的持久性存储,构造方法如下:

      FileOutputStream output=new FileOutputStream( "C:/stu.txt" );

      ObjectOutputStream oos=new ObjectOutputStream( output );

package I_O;

import java.io.*;
import java.util.ArrayList;

public class Test {

	public static void main(String[] args) {
		// 创建序列化对象,注意,必须让Student类实现Serializable接口,否则会抛出java.io.NotSerializableException异常
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream("C:/stu.txt"));
			
			Student stu = new Student("小明",20,"男");
			
			ArrayList<Student> list = new ArrayList<Student>();
			list.add(stu);
			
			oos.writeObject(list);

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (oos != null)
					oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

2、反序列化与序列化相反,看下面代码:

package I_O;

import java.io.*;
import java.util.ArrayList;

public class Test {

	public static void main(String[] args) {
		// 创建反序列化对象
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream("C:/stu.txt"));
			
			ArrayList<Student> list = (ArrayList<Student>) ois.readObject();
			
			for (Student student : list) {
				System.out.println(student.getName());
				System.out.println(student.getAge());
				System.out.println(student.getSex());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				if (ois != null)
					ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 输出:
	 * 小明
	 * 20
	 * 男
	 */

}

十一、重定向输入和输出

package I_O;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		FileInputStream input = null;
		FileOutputStream output = null;
		PrintStream ps = null;
		try {
			input = new FileInputStream("E:/IO/字符流读写/Test1.txt");
			System.setIn(input);

			output = new FileOutputStream("E:/IO/字符流读写/WWTest1.txt", true);
			ps = new PrintStream(output);
			System.setOut(ps);

			Scanner sc = new Scanner(System.in);

			while (sc.hasNextLine()) {
				System.out.println(sc.nextLine());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				if (ps != null)
					ps.close();
				if (output != null)
					output.close();
				if (input != null)
					input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值