欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java IO 文件流

程序员文章站 2024-01-21 18:40:10
...

Java IO 文件流

  • java标准IO input和output 输入与输出
    javaIO让我们以标准的读写形式对设备进行读写操作。并且IO将读写按照方向划分为输入流与输出流

  • 输入流与输出流
    输入流:用于读取数据的流。超类:java.io.InputStream
    输出流:用于写出数据的流。超类:java.io.OutputStream

  • java将流划分为两类:节点流与处理流
    节点流:又称为低级流,是真实连接程序与数据源之间的"管道",负责实际读写数据。
    处理流:又称为高级流,不能独立存在,必须连接在其他流上,作用是在读写的过程中

  • 当数据流经当前流时对其做某些加工处理,简化我们相应的操作。

  • 流可以想象为水管子,里面流的不是水而是字节。但是与现实一样,是按照相同方向顺序流动。因此流是顺序读或顺序写的,读写过程不能回退。

  • 文件流:文件流是一对低级流,用于读写文件数据的流。功能上与RandomAccessFile一样,但是RAF是基于指针的随机读写,而文件流是基于IO的顺序读写。各有优缺点。

  • 文件流常用构造方法:

      FileOutputStream(String path)
      FileOutputStream(File file)
    

这两种方式创建的文件输出流是覆盖写模式,即:如果指定的文件已经存在
,会将该文件原有数据清除。然后再将通过当前流写出的内容保存到文件中。

	  FileOutputStream(String path,boolean append)
	  FileOutputStream(File file,boolean append)

这两种为追加模式,文件若存在则全部数据保留,新写出的内容会被追加到文件中

public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("fos.txt",true);		
		String str = "Hello ";
		byte[] data = str.getBytes("GBK");
		fos.write(data);
		str = "World!";
		data = str.getBytes("GBK");
		fos.write(data);
		//强制将当前缓冲区中已经缓存的数据做一次写出操作
        //bos.flush();
		System.out.println("写出完毕!");
		fos.close();
	}
  • 使用转换流读取文本数据
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("test.txt");
		InputStreamReader isr = new InputStreamReader(fis,"GBK");
		/*
		 * int read()
		 * 读取一个字符并以int型返回,该值为char值,意味着int值低16位有效
		 * 若返回为-1则表示文件末尾
		 */
		int d = 0;
		while((d = isr.read())!=-1){
			char c = (char)d;
			System.out.print(c);
		}
		
		isr.close();
	}
  • 使用文件输入流读取文件数据
public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("fos.txt");
		byte[] data = new byte[1000];
		int len = fis.read(data);//一次性读1000字节
		System.out.println("实际读取到的字节数:"+len);
		//String重载构造方法可以将给定字节数组从指定位置开始连续len个字节转换
		String str = new String(data,0,len,"GBK");
		System.out.println(str);
		
		fis.close();
	}
  • 缓冲字节流
    java.io.BufferedOutputStream和BufferedInputStream
    缓冲字节流是一对高级流,在流链接中起到加快读写效率的作用。

缓冲流在读写数据过程中之所以可以提高读写效率是因为内部有一个字节数组
并且将写出的数据存入数组统一以块写操作进行或一次性读取一组字节的块读
进行从而保证了读写效率。

public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("枯木逢春 - 那年.mp3");
		BufferedInputStream bis = new BufferedInputStream(fis);
		
		FileOutputStream fos = new FileOutputStream("枯木逢春 - 那年_cp.mp3");
		BufferedOutputStream bos = new BufferedOutputStream(fos);
		int d = 0;
		long starts = System.currentTimeMillis();
		
		while((d = bis.read())!=-1) {
			bos.write(d);
		}
		long ends = System.currentTimeMillis();
		System.out.println("复制完毕!耗时"+(ends-starts)+"ms");
		
		bis.close();
		bos.close();
	}
  • 对象序列化:将一个对象按照其结构转换为一组字节的过程
//一个类的实例若希望被对象流读写,这个类必须实现java.io.Serializable接口
public class Person implements Serializable{
	private static final long serialVersionUID = -3177580858567550035L;
	private String name;
	private int age;
	private String gender;
	/*
	 * transient关键字
	 * 当一个属性被transient修饰后,那么当该类的实例进行序列化时
	 * 这个属性的值会被忽略。忽略不必要的属性可以达到对象瘦身的效果
	 * 减少资源开销。
	 */
	private transient String[] otherInfo;
	public Person(String name, int age, String gender, String[] otherInfo) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.otherInfo = otherInfo;
	}
	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 String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String[] getOtherInfo() {
		return otherInfo;
	}
	public void setOtherInfo(String[] otherInfo) {
		this.otherInfo = otherInfo;
	}

	public String toString() {
		return name+","+age+","+gender+","+Arrays.toString(otherInfo);
	}

对象流:对象流是一对高级流,在流链接中的作用是进行对象序列化与反序列化。便于我们读写 java中任何对象。

public static void main(String[] args) throws IOException {
		String name = "张三";
		int age = 20;
		String gender = "男";
		String[] otherInfo = {"学习好","自学编程","爱打篮球","擅长运球突破","中投王"};
		Person p = new Person(name, age, gender, otherInfo);
		System.out.println(p);
		//将Person对象写入文件保存
		FileOutputStream fos = new FileOutputStream("person.obj");
		ObjectOutputStream oos = new ObjectOutputStream(fos);
	
		oos.writeObject(p);
		System.out.println("写出完毕!");
		oos.close();
		
		
	}

对象输入流,进行对象的反序列化

public static void main(String[] args) throws IOException, ClassNotFoundException {
		FileInputStream fis = new FileInputStream("person.obj");
		ObjectInputStream ois = new ObjectInputStream(fis);
		/*
		 * Object readObject()
		 * 将读取到的字节按照其结构还原为java对象的过程称为对象的反序列化	
		 */
		Person p = (Person)ois.readObject();
		System.out.println(p);
		
		ois.close();
	}
  • 使用文件流完成文件的复制(用块读写完成)
    步骤:

       1:创建文件输入流读取原文件
       2:创建文件输出流写复制文件
       3:循环通过文件输入流读原文件数据(一次10kb)并通过文件输出流写入
         复制文件,直到复制完毕。
       4:关闭两个流  
    
public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("music.mp3");
		FileOutputStream fos = new FileOutputStream("music_cp3.mp3");
		
		int d = 0;
		byte[] data = new byte[1024*10];//10kb
		while((d = fis.read(data))!=-1) {
			fos.write(data,0,d);
		}
		
		System.out.println("复制完毕!");
		fis.close();
		fos.close();
	}
  • 将当前源代码输出到控制台
public class BRDemo {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("./src/io/BRDemo.java");
		InputStreamReader isr = new InputStreamReader(fis);
		BufferedReader br = new BufferedReader(isr);		
		String line = null;
		/*
		 * String readLine()
		 * 读取一行字符串,该方法会读取若干字符,当读取到换行符时停止,并将换行符
		 * 之前的内容以一个字符串形式返回。若返回值为null时表示流读取到了末尾。
		 */
		while((line = br.readLine())!=null) {
			System.out.println(line);
		}
		br.close();
	}
}

  • 字符流
    javaIO将流按照读写单位划分为了字节流与字符流
    字符流的两个超类:
  • java.io.Writer:所有字符输出流的超类
  • java.io.Reader:所有字符输入流的超类

字符流底层实际还是读写字节,只不过字符与字节的转换由字符流完成。让我们可以以最小单位为char来进行文本数据的读写。由于字符流读写单位是字符,因此字符流只适合读写文本数据!

  • 转换流:
    java.io.InputStreamReader和java.io.OutputStreamWriter
    他们是一对高级流,很常用的一对字符流实现类,在流连接中是重要的一环,但是我们不直接操作他们。
    其他功能更多的字符流都有一个特点,在流链接中只能链接其他的字符流,是不能直接链接字节流的,而转换流是唯一一个可以链接字节流的字符流,因此在流链接串联它就可以起到让其他字符流链接字节流的目的了,相当于是一个"转换器"的作用。
    常用构造方法:

      * OutputStreamWriter(OutputStream out)
      * 使用默认字符集将要写出的文本数据转换为字节后写出
      
      * OutputStreamWriter(OutputStream out,String csn)
      * 按照指定的字符集转换
    
public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("osw.txt");
		OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
		osw.write("Hello ");
		osw.write("World!");
		
		System.out.println("写出完毕!");
		osw.close();
	}
  • 缓冲字符流
    java.io.BufferedWriter和java.io.BufferedReader
    缓冲字符流内部有缓冲区(字符数组)可以做到块读写文本数据加快读写效率。
    并且缓冲字符流还可以按行读写文本数据。
    java.io.PrintWriter是具有自动行刷新的缓冲字符输出流,内部总是链接BufferedWriter作为缓冲功能。

       向文件中写入字符串
       PrintWriter提供了直接对文件写操作的构造方法:
       PrintWriter(String fileName)
       PrintWriter(File file)
       以上两个构造方法都支持一个重载,传入第二个参数,指定字符集名字
       这样就可以按照指定的字符集向文件中写入文本数据了
    
public static void main(String[] args) throws IOException {
		PrintWriter pw = new PrintWriter("pw.txt","GBK");
		pw.print("Hello ");
		pw.println("World!");
		
		System.out.println("写出完毕!");
		pw.close();
	}
  • 自行使用流链接完成文本数据写出操作
public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("pw2.txt");
		OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");
		BufferedWriter bw = new BufferedWriter(osw);
		PrintWriter pw = new PrintWriter(bw);
		
		pw.print("Hello ");
		pw.println("World!");
		
		System.out.println("写出完毕!");
		pw.close();
	}
相关标签: 笔记

上一篇: Java 文件IO流

下一篇: