黑马程序员_Java基础_IO

---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

一、java IO部分概述:

在JavaIO部分从大的范围来说,有四个部分需要掌握
1 File类 文件操作相关类
2 RandomAccessFile类 随机存取文件类
3 字节流(InputStream、OutputStream) 字节操作类
4 字符流(Reader、Writer) 字符操作类

二、分类介绍

1、File类介绍:
构造方法:

File(File parent,String child) 根据父路径与给定文件名创建文件

File(String name) 根据指定文件名创建文件

File(String parent,String child) 与第一个方法差不多

File(URI uri) 把String类型的路径封装为URI,再创建文件

常用的方法
createNewFile(),当文件不存在是创建文件
delete(),删除文件,或者目录
exists(),判断文件是否存在
getAbsolutePath()与getAbsoluteFile()返回绝对路径
getPath()返回此文件的路径名
getParent()返回此文件父路径
getParentFile()返回此文件父路径的文件
isDirectory()是否为目录
isFile()是否为标准的文件
isHidden()是否是隐藏文件
mkdir()创建此抽象路径名指定的目录
mkdirs()创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
list()返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
listFiles()返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
   

package com.itheima.io;

import java.io.File;

/**
 * JavaIO概述:
 *
 */
public class IOSummary {

	public static void main(String[] args)throws Exception {
		//声明一个文件(目录)
		File fileDir = new File("aa1/aa/aa/aa");
		//判断文件是否存在,如果不存在就创建
		if(!fileDir.exists()){
			//mFile.mkdir();//创建单层目录,如果aa1/aa/aa不存在上述目录创建时就会报错
			fileDir.mkdirs();//创建多层目录
		}
		File file1 = new File(fileDir,"aa.txt");
		file1.createNewFile();//真正的创建文件
		System.out.println(file1.getAbsolutePath());//得到绝对路径
		File fileDir1 = new File("aa1");
		fileDir1.delete();//删除文件,如果删除成功返回true,
		//删除成功的条件,是一个文件,或者目录下面没有其他文件或者目录
		System.out.println(file1.getParent());//返回父目录
		String[] dirs = fileDir1.list();//列出指定目录下的文件或者目录(文件夹),支持一层
		for (String dir : dirs) {
			System.out.println(dir);
		}
		listAll(fileDir1);
	}
	
	/**
	 * 列出给定目录下的全部文件或者目录
	 */
	public static void listAll(File rootFile){
		if(rootFile.isDirectory()){//判断给定的文件是否是目录,如果是目录
			//列出该目录下的所有文件
			File[] files = rootFile.listFiles();
			//迭代各个文件
			for (File file : files) {
				if(file.isDirectory()){//如果文件是目录
					listAll(file);//列出目录下的所有文件
					System.out.println("目录:"+file);//打印目录
				}else{
					System.out.println("文件:"+file);//打印文件
				}
			}
		}else{
			System.out.println("文件"+rootFile);
		}
	}
}
2、RandomAccessFile类介绍

RandomAccessFile类是文件随机读写的类,提供了文件随机读写的操作方法

构造方法:
RandomAccessFile(File file,String mode)
RandomAccessFile(String file,String mode)
常用方法
close()关闭流对象
getChannel()得到管道流对象
length()返回文件大小
read对应的各种读取方法
write对应的各种写方法
setLength()设置文件的长度
seek(long pos)设置文件指针相对于开始位置的偏移量,从pos开始操作此文件

关于RandomAccessFile类的练习:模拟多线程下载文件

package com.itheima.io;

import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 文件随机读取访问
 * 模拟多线程下载文件
 */
public class RandomAccessFileDemo {

	public static void main(String[] args) throws Exception{
		//创建一个文件
		RandomAccessFile file = null;
		String urlPath = "http://124.192.132.168/file/MDAwMDAwMDHKGp_9qE8zoJrzb_-3RgszOiyRKeOXN4q9wsoiUPdNuQ../39f1e5060cc9a94c6d2a13ef6fc1ebf62045066/%E9%BB%91%E9%A9%AC%E7%A8%8B%E5%BA%8F%E5%91%98_%E6%AF%95%E5%90%91%E4%B8%9C_Java%E5%9F%BA%E7%A1%80%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B%E7%AC%AC18%E5%A4%A9-01-%E5%85%B6%E4%BB%96%E5%AF%B9%E8%B1%A1%28System%29.zip?key=AAABQFLyGGG8K6oy&p=&a=10361271-31ddf865-48049-0/010135&c=lr:fcc824288070710f29ab472e717e5379/3072k&mode=download";
		URL mUrl = new URL(urlPath);
		HttpURLConnection conn = (HttpURLConnection) mUrl.openConnection();
		if(conn.getResponseCode() == 200){
			file = new RandomAccessFile("黑马视频.zip","rw");
			long fileLength = conn.getContentLengthLong();
			file.setLength(fileLength);//设置文件长度
			
			int threadNumber = 4;//假设由4个线程同时启动下载程序
			//计算每个线程应该下载的范围
			long oneThreadDownLength = fileLength%threadNumber ==0 ?fileLength/threadNumber:fileLength/threadNumber+1;
			for(int i=1;i<=threadNumber;i++){
				long start = (i-1)*oneThreadDownLength;
				long end = oneThreadDownLength*i;
				if(i == threadNumber){
					end = fileLength;
				}
				
				new Thread(new DownLoad( mUrl, start, end)).start();
				
			}
		}
	}
	
}
//多线程下载文件
class DownLoad implements Runnable{
	private	long startPos ; //下载的开始位置
	private long endPos;//下载的结束位置
	private URL urlPath;
	public DownLoad(URL urlPath,long startPos,long endPos){
		this.startPos = startPos;
		this.endPos = endPos;
		this.urlPath = urlPath;
	}
	@Override
	public void run() {
		//链接网络
		try{
			HttpURLConnection conn = (HttpURLConnection) urlPath.openConnection();
			conn.setRequestProperty("Range", "bytes="+startPos+"-"+endPos);
			RandomAccessFile file = new RandomAccessFile("黑马视频.zip","rw");
			if(conn.getResponseCode() == 206){
				
				InputStream ins = conn.getInputStream();
				byte[] buf = new byte[1024*1024];
				int len = -1;
				file.seek(startPos);//设置开始写入的位置
				System.out.println("开始位置:"+startPos);
				while((len = ins.read(buf))!=-1){
					file.write(buf,0,len);
				}
				ins.close();
				file.close();
				System.out.println(startPos+"===="+endPos+"下载完毕");
			}
		}catch(Exception e){
			e.printStackTrace();
			System.out.println("下载文件失败");
		}
	}
}
以上方法,模拟下载黑马训练营中的一个文件 我用20个线程与一个线程下载时间差不多。。。难道是我网速问题?


3、字节流

字节流有两个基类:InputStream、OutputStream

字节流相关操作类的继承关系如下:

黑马程序员_Java基础_IO_第1张图片
下面使用在代码中大概介绍下

FileInputStream与OutputStream介绍,构造方法与常用API可以看JavaAPI文档

package com.itheima.io;

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

/**
 * 在本示例中介绍FileInputStream与FileOutputStream
 * 案例:完成文件的复制
 */
public class FileStreamDemo {

	public static void main(String[] args) throws Exception{
		String srcFilePath = "src/com/itheima/io/RandomAccessFileDemo.java";
		String destFileDir = "";
		copyFile(srcFilePath, destFileDir);
	}
	public static void copyFile(String srcFilePath,String destFileDir)throws Exception{
		FileInputStream fis = new FileInputStream(srcFilePath);
		if(srcFilePath == null || srcFilePath.isEmpty()){
			throw new IllegalArgumentException("src file cannot empty.");
		}
		String fileName = null;
		if(srcFilePath.contains("/")){
			fileName = srcFilePath.substring(srcFilePath.lastIndexOf("/")+1);
		}else{
			fileName = srcFilePath;
		}
		File file = null;
		if(destFileDir == null || destFileDir.isEmpty()){
			file = new File(fileName);
		}else{
			file = new File(destFileDir,fileName);
		}
		FileOutputStream fos = new FileOutputStream(file);
		byte[] buf = new byte[1024];
		int len = -1;
		while((len = fis.read(buf))!=-1){
			fos.write(buf,0,len);//在这里没有进行flush()操作,因为缓冲区数据满的话,会自动flush的
		}
		fos.close();
		fis.close();
	}
}
BufferedInputStream与BufferedOutputStream介绍,带有缓冲区的流对象

package com.itheima.io;

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

/**
 * 带有缓冲区的流对象
 * 还是复制文件的案例,代码与前一个代码相同
 */
public class BufferedStreamDemo {
	
	public static void main(String[] args) throws Exception{
		String srcFilePath = "RandomAccessFileDemo.java";
		String destFileDir = "aa1/aa/ddd";
		copyFile(srcFilePath, destFileDir);
	}
	public static void copyFile(String srcFilePath,String destFileDir)throws Exception{
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFilePath));
		if(srcFilePath == null || srcFilePath.isEmpty()){
			throw new IllegalArgumentException("src file cannot empty.");
		}
		String fileName = null;
		if(srcFilePath.contains("/")){
			fileName = srcFilePath.substring(srcFilePath.lastIndexOf("/")+1);
		}else{
			fileName = srcFilePath;
		}
		File file = null;
		if(destFileDir == null || destFileDir.isEmpty()){
			file = new File(fileName);
		}else{
			file = new File(destFileDir,fileName);
		}
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
		
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = bis.read(buf))!=-1){
			bos.write(buf, 0, len);
		}
		bis.close();
		bos.close();
	}
}
4、ObjectOutputStream与ObjectInputStream使用

package com.itheima.io;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 把一个Person对象存入文件中,并且读出来
 * 前提是:要操作的Object对象需要实现Serializable接口
 */
public class ObjectStreamDemo {

	public static void main(String[] args) throws Exception{
		Person p = new Person();
		p.setName("张三");
		p.setAge(30);
		//writeObj(p);
		readObj(Person.class);
	}
	
	public static void writeObj(Serializable obj)throws Exception{
		ObjectOutputStream ops = new ObjectOutputStream(new FileOutputStream("person.project"));
		ops.writeObject(obj);
		System.out.println("写入文件成功");
	}
	
	public static void readObj(Class clazz)throws Exception{
		ObjectInputStream ips = new ObjectInputStream(new FileInputStream("person.project"));
		Object obj = ips.readObject();
		//想把类的全名转化为实际的类型,例如"com.itheima.io.Person"-->com.itheima.io.Person
		//晕,不知道怎么实现,难道无解?
		T result = clazz.cast(obj);//强不强转无所谓
		System.out.println(result);
	}
}
在上面的例子中Person类的代码没有贴出来,里面只有两个字段,String类型的name与int类型的age

5、SequenceInputStream合并流的操作

package com.itheima.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

/**
 * 本实例中主要说明:
 * SequenceInputStream
 * 
 * 这两个接口可以实现文件的拼接
 */
public class SequenceStreamDemo {

	public static void main(String[] args) throws Exception{
		File file = new File("a.jpg");
		split(file,6000);//拆分文件
		merge();//合并文件
	}
	
	/**
	 * 合并文件
	 */
	public static void merge()throws Exception{
		List list = new ArrayList();
		for(int i=1;i<=7;i++){
			list.add(new FileInputStream(i+".part"));
		}
		final Iterator iterator = list.iterator();
		Enumeration e = new Enumeration() {
			public boolean hasMoreElements() {
				return iterator.hasNext();
			}
			public InputStream nextElement() {
				return iterator.next();
			}
		};
		SequenceInputStream sis = new SequenceInputStream(e);
		FileOutputStream fos = new FileOutputStream("result.jpg");
		byte[] buf = new byte[1024];
		int len = -1;
		while((len = sis.read(buf))!=-1){
			fos.write(buf,0,len);
		}
		fos.close();
		sis.close();
	}
	
	
	/**
	 * @param file 源文件
	 * @param size 每个文件的大小 单位字节
	 * @throws Exception
	 */
	public static void split(File file,int size)throws Exception{
		FileInputStream fis = new FileInputStream(file);
		FileOutputStream fos = null;
		byte[] buf = new byte[size];
		int len = -1;
		int block = 1;
		while((len = fis.read(buf))!=-1){
			fos = new FileOutputStream(block++ +".part");
			fos.write(buf,0,len);
			fos.close();
		}
		fis.close();
	}
}
6、数组的内存操作ByteArrayInputStream与ByteArrayOutputStream操作

package com.itheima.io;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * 本实例主要讲解ByteArrayInputStream与ByteArrayOutputStream
 * 作用:提供数组在内存中的操作流
 */
public class ByteArrayStream {

	public static void main(String[] args) throws Exception{
		memory();
	}
	
	public static void memory()throws Exception{
		ByteArrayInputStream bis = new ByteArrayInputStream("黑马程序员训练营".getBytes());
		
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		byte[] buf = new byte[1024];
		int len = -1;
		while((len = bis.read(buf))!=-1){
			bos.write(buf,0,len);
		}
		System.out.println(bos.toString());
	}
}

7、字符流的操作,基本上与字节流完全一样,下面只用BufferedReader类与BufferedWriter为例子介绍

package com.itheima.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/**
 * 字符流的操作
 * 本实例完成的功能是通过键盘输入写入文件中
 */
public class BufferedDemo {

	public static void main(String[] args) throws Exception{
		writeToFile();
	}
	public static void writeToFile()throws Exception{
		//缓冲流									    //把字节流转换为字符流,同时设置字符编码
		BufferedReader mReader = new BufferedReader(new InputStreamReader(System.in,"GBK"));
		BufferedWriter mWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("console.txt"),"GBK"));
		
		String line = null;
		while((line = mReader.readLine())!=null){
			if(line.equals("over")){
				break;
			}
			mWriter.write(line);
			mWriter.newLine();
			mWriter.flush();
		}
		mReader.close();
		mWriter.close();
	}
	
}

三、IO学习总结

JavaIO中,所有的类大部分都是成对出现的,字符流能完成的功能字节流全部都能完成,基本的操作方法基本一致。File类对文件的操作不会创建文件,流对文件的操作都会创建文件,RandomAccessFile类当文件不存在是如果文件的操作模式是“r”的话,会报异常,如果是“rw”时,会创建文件。


---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net

你可能感兴趣的:(学习笔记)