DAY18-IO字节输入输出流

## 今日内容:IO流

遍历电脑所有盘符下的文件和文件夹名

import java.io.File;
//遍历所有盘下有访问权限的文件及文件夹的名字
public class Demo8 {
	public static void main(String[] args){
		File[] roots=File.listRoots();//listRoots()方法获取电脑所有盘符的根目录名
		for(File root:roots){
			getFiles(root);
		}
}

	public static void getFiles(File dir){
/*进入这个方法的前提是输入的参数为一个文件夹路径,如果是文件路径的话那么这句话执行结束后就不会再输出文件夹名了,这句话
在这里的作用仅仅是输出文件夹名*/
		System.out.println("......"+dir);
		
/*注意:listFiles方法返回一个抽象路径名数组表示文件的路径.如果调用这个方法的抽象路径名不表示一个目录,那么此方法将
 * 返回 null。否则返回一个 File 对象数组,每个数组元素对应目录中的每个文件或目录。*/
		File[] files=dir.listFiles();
		System.out.println(files);
		//如果指定的目录java没有权限,这是list或者listFiles方法返回的结果是null,为了让程序运行,要排除这种情况
		if(files!=null){
			for(File file:files){
				if (file.isDirectory()) {
					getFiles(file);
				}else{
					System.out.println(file);//默认调用了toString方法
				}
			}
		}
	}
}

IO

从内存角度看,数据流向内存的---输入技术,数据从内存流出的---输出技术

按照数据的流向:

输入流:指的是数据源中的数据流向内存

输出流:指的是数据从内存中流向目的地

按照操作的数据类型分为:

字节流:操作字节数据,如图片,音频,视频,文本等二进制类型文件,字节流可以操作任何数据类型数据;

字符流:操作字符数据,如文本,相当于字节流+编码表。

字节输入流:InputStream

输出所有的字节编码

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

public class Demo5 {
	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("D:\\ATT.txt");
		for (int i = 0; i < 65536; i++) {//输出所有的字节编码
			fos.write(i);
		}
		fos.close();
		System.out.println("Done!");
	}
}
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

//IO技术,read()每次读取一个字节
public class Demo1 {
	public static void main(String[] args) throws IOException {
		File file=new File("D:\\Javacode\\DAY18\\src\\Demo1\\Demo1.java");
		FileInputStream fis=new FileInputStream(file);
		int a=fis.read();
		while(a!=-1){
			 a=fis.read();
			System.out.print((char)a);
		}
		fis.close();
	}
}
import java.io.FileInputStream;
import java.io.IOException;

//byte[],每次读取一个字节数组,字节数组大小是自定义的
public class Demo2 {
	public static void main(String[] args) throws IOException {
		FileInputStream fis=new FileInputStream("b.doc");
		byte[] by=new byte[1024];//创建一个接受读取内容的字节数组
		int num=fis.read(by);//每次读取一个字节数组,返回读取的字节个数
		while(num!=-1){
			System.out.print(new String(by,0,num));//必须用String字符串的这种构造方法,否则会多打出一部分内容
			num=fis.read(by);
		}
	}
}

read(); 返回一个字节数据,读取到文件末尾后没有更多数据则返回-1,如果数据占用多个字节,只会读取最低的8位字节,其他的忽略不读取;

read(byte[]); 返回读取字节数组数据的实际个数,读到末尾没有更多数据返回-1;

read(byte[],index,len); 读取字节数组的部分数据,返回int值,表示读取了多少个字节;

close();关闭输入或输出流

flush(); 刷新数据

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

//FileOutputStream,write
public class Demo3 {
	public static void main(String[] args) throws IOException {
		FileOutputStream fos=new FileOutputStream("a.docx");
		for (int i = 0; i < 5; i++) {
			byte[] by="Hello,Java\r\n".getBytes();
			fos.write(by,0,by.length);
		}
		fos.close();
	}
}

创建FileOutputStream对象时,如果文件不存在则创建该文件,如果文件已存在则覆盖,注意不能创建文件夹。

windows系统下的换行为:\r\n

构造方法FileOutputStream(File,boolean,append),如果文件不存在就创建文件,boolean为true时,如果文件已存在的话就在他后面添加内容,不会进行覆盖boolean=false依然会进行覆盖。

字节缓冲流的目的是加快基础流的读写操作,方法都差不多。

字节输入输出流和字节缓冲输入输出流速度对比:

//尝试捕获异常
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//尝试剪切操作
//复制图片视频到指定目录下,程序员改变生活~
public class Demo4 {
	public static void main(String[] args) {
		// 建立连接
		// 创建输入流
		long start=System.currentTimeMillis();
		FileInputStream fis = null;// 创建字节输入流对象
		FileOutputStream fos = null;// 创建字节输出流对象

		try {
			fis = new FileInputStream("E:\\win7.rar");
			fos = new FileOutputStream("D:\\win7.rar");// 精确到文件名
			// 读取文件
			byte[] by = new byte[1024];// 创建一次读取多少字节的字节数组
			int len = 0;// 指的是read返回的int值,是读取了多少字节数
			while ((len = fis.read(by)) != -1) {
				fos.write(by, 0, len);// 写入文件
			}
		} catch (IOException e) {
			e.printStackTrace();

		} finally {// 不管输入输出流是否成功,都需要断开连接,是必须执行的,因此要放在finally中
			try {
				if (fis != null)// 如果字节出入流为空的话那么就没有创建他的对象,就不能关闭它
					fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (fos != null)// 如果字节输出流为空的话那么就没有创建他的对象,就不能够关闭它
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			long end=System.currentTimeMillis();
			long time=end-start;
			System.out.println("程序运行共花了:"+time/1000+"秒");
		}
	}
}
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

//BufferedInputStream,加速FileInputStream的效率
public class Demo5 {
	public static void main(String[] args) {
		// 计算程序运行花的时间,和普通字节输入流比较一下效率
		long start = System.currentTimeMillis();// 获得程序开始时间

		/*
		 * 创建字节输入输出缓冲流对象,放到try/catch外面,因为finally中的close方法还要用到,局部变量必须赋初值,因为是对象,
		 * 引用类型的,所以赋值null。地下的close还要重新创建try/catch,因为他们在finally中没有被try/catch包围
		 */
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(new FileInputStream("E:\\win7.rar"));
			bos = new BufferedOutputStream(new FileOutputStream("D:\\win7.rar"));
			// 首先创建字节输入流对象
			byte[] by = new byte[1024];// 创建一个缓冲数组
			int len = 0;// 读取的字节数
			while ((len = bis.read(by)) != -1) {
				bos.write(by, 0, len);// 写入数据
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			if (bis != null)
				bis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			if (bos != null)
				bos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		long end=System.currentTimeMillis();
		Long time=end-start;
		System.out.println("程序运行共花了:"+time/1000+"秒");
	}
}

实现剪切操作

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

//实现剪切的操作
/*创建输入流对象
执行read操作
创建输出流对象
执行write操作
等到执行完write操作之后执行delete操作*/
public class Demo6 {
	public static void main(String[] args) {
		File file = new File("D:\\新建文件夹\\2.jpg");
		// file.delete();
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream(file);
			fos = new FileOutputStream("D:\\1.jpg");
			byte[] by = new byte[1024];// 定义一个字节数组,每次都读取字节数组大小的数据
			int num = 0;// 用于记录返回的读取的字节个数
			while ((num = fis.read(by)) != -1) {
				fos.write(by);
			}
			if (num == -1) {
				
/*此处必须先断开输入输出流的连接,否则次文件被占用就删不掉,这也是finally为什么要执行该操作,就是为了释放系统资源,
解除对该文件的占用,这里断开连接不会和底下finally中的操作冲突,因为他们已经提前判断fis和fos是否为空了*/
				fis.close();
				fos.close();
				file.delete();
			}
			System.out.println("剪切操作已完成!");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (fis != null)
					fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if (fos != null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

文件切割合并

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

public class Demo6 {
	public static void main(String[] args) throws IOException {
		cutFile();
		mergeFile();
	}
	//切割文件
	public static void cutFile() throws IOException{
		FileInputStream fis=new FileInputStream("D:\\1.jpg");
		int count=1;//碎片片段
		byte[] buf=new byte[102400];//每个碎片的大小
		int len=0;
		while((len=fis.read(buf))!=-1){
			FileOutputStream fos=new FileOutputStream("E:\\"+count+".jpg");
			fos.write(buf,0,len);
			
/*每写完一个文件就关一次流,因为是写成碎片文件,每个碎片文件都是一个独立的流,关的是写入的流而不是读取的流,
所以保证了读取的始终是同一个文件*/
			fos.close();
			count++;
		}
		fis.close();//等到所有文件都读完了再关闭读取的流
	}
	//合并文件
	public static void mergeFile() throws IOException{
		FileOutputStream fos=new FileOutputStream("D:\\2.jpg");//拼接文件,所以写的流最后关
		File file=new File("D:\\1.jpg");
		//三元,判断碎片个数
		int count=(int) (file.length()%102400==0?file.length()/102400:file.length()/102400+1);
		
		for(int i=1;i<=count;i++){
			FileInputStream fis=new FileInputStream("E:\\"+i+".jpg");
			byte[] buf=new byte[1024];
			int len=0;
			while((len=fis.read(buf))!=-1){
				fos.write(buf,0,len);
			}
			fis.close();
		}
		fos.close();
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42837554/article/details/88538868