Java学习笔记(38)-I/O输入/输出流

时间:2022-01-19 11:50:16

Java I/O 输入/输出

流:

根据方向流分为:输入流和输出流

方向的定论是基于我们的程序。

流向我们程序的流叫做:输入流

从程序向外流的叫做:输出流

我们可以把流想象为管道。管道里流动的是水,而java中的流,流动的是字节。

输入流是用于获取数据的。输出流是用于向外输出数据的。

输入流是用于读取的,输出流是用于写出的。

java中

InputStream:该接口定义了输入流的特征

OutputStream:该接口定义了输出流的特征

流根据源头:

分为:基本流(低级流,节点流):有来源。

           处理流(高级流,过滤流):没有数据来源。不能独立存在。它的存在是用于处理基本流的。

流根据处理的数据单位不同划分为:

字节流:Stream

字符流:Reader/Writer

用于读写文件的字节流FIS/FOS

FileInputStream:文件输入流

FileOutPutStream:文件输出流

FileOutputStream用于向文件中写入数据。

构造其实例可以使用

FileOutputStream(File file):

向file文件中写入数据。若该文件不存在,则会创建该文件。

package day02;

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

/**
 * 文件字节输入流
 * FileInputStream:用于读取内容的流
 * @author Administrator
 *
 */
public class DemoFileInputStream {
	public static void main(String[] args) throws IOException {
		File file = new File("data.dat");
		/**
		 * 根据文件创建用于读取其数据的文件输入流
		 */
		FileInputStream fis = new FileInputStream(file);
		
//		int b = fis.read();
		int b = 0;
		while((b = fis.read())!=-1){
			//输出这个字节的16进制形式
			System.out.print(Integer.toHexString(b)+" ");
		}
		fis.close();//切记,流用完了要关闭!
	}
}
package day02;

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

/**
 * IO工具类
 * @author Administrator
 *
 */
public class IOUtils {
	/**
	 * 读取给定的文件,并将数据已字节数组的形式返回
	 * @param src
	 * @return
	 * @throws IOException
	 */
	public static byte[] loadBytes(File src) 
							throws IOException{
		if(src==null){
			throw new IllegalArgumentException("文件为空!");
		}
		if(!src.exists()){
			throw new IllegalArgumentException(src+"不存在!");
		}
		FileInputStream fis = null;//创建文件输入流
		try{
			fis = new FileInputStream(src);
//			byte[] data = new byte[(int)src.length()];
			/**
			 * FileInputStream的available()方法:
			 *  返回当前字节输入流可读取的总字节数
			 */
			byte[] data = new byte[fis.available()];
			fis.read(data);
			return data;
		}catch(IOException e){
			throw e;//读取出现错误将异常抛给调用者解决
		}finally{
			if(fis!=null){
				fis.close();
			}
		}
	}
}
package day02;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

/**
 * 测试IOUtils工具类
 * @author Administrator
 *
 */
public class TestIOUtils {
	public static void main(String[] args) {
		File file = new File("data.dat");
		try{
			//将文件数据读取出来
			byte[] data = IOUtils.loadBytes(file);
			
			//输出文件内容
			System.out.println(Arrays.toString(data));
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

package day02;

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

/**
 * 测试文件输出流
 * FileOutputStream
 * write(int d):写int值得低8位
 * write(byte[] d):将d数组中所有字节写出
 * write(byte[] d,int offset,int length);
 * 将d数组中offset位置开始写length个字节
 * @author Administrator
 *
 */
public class DemoFileOutputStream {
	public static void main(String[] args) throws IOException {
		File file = new File("out.txt");
		if(!file.exists()){
			file.createNewFile();
		}
//		FileOutputStream fos  = new FileOutputStream(file);
		/**
		 * FileOutputStream(File file,boolean append)
		 * FileOutputStream(String filePath,boolean append)
		 * append为true:会在当前文件末尾进行写操作
		 */
		FileOutputStream fos = new FileOutputStream(file,true);
		String info = "你好!输出流!";
		byte[] data = info.getBytes("UTF-8");
		fos.write(data);//将字符串转换的字节写出
		fos.close();
	}
}

BufferedInputStream:缓冲字节输入流

BufferedOutputStream:缓冲字节输出流

内部维护着一个缓冲区,可以提高读写效率,缓冲字节输入输出流是高级流。

辨别高级流的简单方法:

看构造方法,若构造方法要求传入另一个流,那么这个流就是个高级流。

package day02;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * IO工具类
 * 
 * @author Administrator
 *
 */
public class IOUtils {
	/**
	 * 数据源 DataSource 将给定数组写入给定文件中
	 * 
	 * @param src
	 * @param data
	 * @throws IOException
	 */
	public static void saveBytes(File src, byte[] data) throws IOException {
		if (src == null) {
			throw new IllegalArgumentException("文件为空!");
		}
		// 创建文件输出流
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(src);
			fos.write(data);
		} catch (IOException e) {
			throw e;
		} finally {
			if (fos != null) {
				fos.close();
			}
		}
	}

	/**
	 * 将src文件复制保存到des文件
	 * 
	 * @param src
	 * @param des
	 * @throws IOException
	 */
	public static void copyFile(File src, File des) throws IOException {
		if (src == null) {
			throw new IllegalArgumentException("源文件为空!");
		}
		if (!src.exists()) {
			throw new IllegalArgumentException("源文件不存在!");
		}
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream(src);
			fos = new FileOutputStream(des);
			int data = -1;
			while ((data = fis.read()) != -1) {
				fos.write(data);
			}

		} catch (IOException e) {
			throw e;
		} finally {
			if (fis != null) {
				fis.close();
			}
			if (fos != null) {
				fos.close();
			}
		}

	}

	/**
	 * 使用缓冲流进行文件拷贝
	 * 
	 * @param src
	 * @param des
	 * @throws IOException
	 */
	public static void copyFile2(File src, File des) throws IOException {
		if (src == null) {
			throw new IllegalArgumentException("源文件为空");
		}
		if (!src.exists()) {
			throw new IllegalArgumentException("源文件不存在");
		}
		/**
		 * 创建缓冲流 自动导包快捷键:ctrl+shift+o
		 */
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(new FileInputStream(src));
			bos = new BufferedOutputStream(new FileOutputStream(des));
			int data = -1;
			while ((data = bis.read()) != -1) {
				bos.write(data);
			}
			/**
			 * flush的作用是将缓冲区中未写出的数据一次性写出
			 */
			bos.flush();//数据都写完后应该flush
		} catch (IOException e) {
			throw e;
		} finally {
			if (bis != null) {
				/**
				 * 通常情况下,我们只需要关闭最外层的流
				 */
				bis.close();
			}
			if (bos != null) {
				bos.close();
			}
		}

	}

	/**
	 * 读取给定的文件,并将数据已字节数组的形式返回
	 * 
	 * @param src
	 * @return
	 * @throws IOException
	 */
	public static byte[] loadBytes(File src) throws IOException {
		if (src == null) {
			throw new IllegalArgumentException("文件为空!");
		}
		if (!src.exists()) {
			throw new IllegalArgumentException(src + "不存在!");
		}
		FileInputStream fis = null;// 创建文件输入流
		try {
			fis = new FileInputStream(src);
			// byte[] data = new byte[(int)src.length()];
			/**
			 * FileInputStream的available()方法: 返回当前字节输入流可读取的总字节数
			 */
			byte[] data = new byte[fis.available()];
			fis.read(data);
			return data;
		} catch (IOException e) {
			throw e;// 读取出现错误将异常抛给调用者解决
		} finally {
			if (fis != null) {
				fis.close();
			}
		}
	}
}
package day02;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

/**
 * 测试IOUtils工具类
 * @author Administrator
 *
 */
public class TestIOUtils {
	public static void main(String[] args) {
		File file = new File("data.dat");
		try{
//			//将文件数据读取出来
//			byte[] data = IOUtils.loadBytes(file);
//			
//			//输出文件内容
//			System.out.println(Arrays.toString(data));
//			File des = new File("abc.dat");//该文件在磁盘上不存在
//			IOUtils.saveBytes(des,data);
			File src = new File("1.zip");
			File des = new File("11.zip");
			IOUtils.copyFile2(src,des);
		}catch(IOException e){
			e.printStackTrace();
		}
	}
}

DataInputStream:可以直接读取基本类型数据的流。

DataOutputStream:可以直接写基本数据的流,简化了对基本类型数据的读写操作。

DIS:int readInt():连续读取4个字节,返回该int值。

doutble readDouble():连续读取8个字节,返回double值。

String readUTF():

DOS:

writeInt(int i):

writeLong(long i):

writeUTF(String s):