黑马程序员-IO

IO流用来处理设备之间的数据传输。
按数据分为两种:字节流和字符路。
流向分为:输入流。输出流。
字节流的抽象基类:InputStream,OutputStream。
字符流的抽象基类:Reader,Writer。
FileWriter:创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。而且该文件会被创建到知道目录下,如果该目录下已有同名文件。将被覆盖。该步是明确数据要存放的目的地。
FileWriter fw = new FileWriter("d.txt");
fw.write("abc"); 字符串写入到流中。
fw.flush();刷新流对象中的缓冲数据,将数据刷到目的地中。
fw.close();关闭流资源。关闭之前会刷新一次缓冲数据。
IOException处理方式:
public static void main(String[] args){
		FileWriter fw = null;
			try
			{ 
			   fw = new FileWriter();
			   fw.write("abc");
			}
			catch(IOException e)
			{
				System.out.print(e.toSring());
			}
			finally
			{
				try
				{
					if(!fw==null)
					fw.close();
				}
				catch(IOException e)
				{
					System.out.print(e.toSring());
				}
			}
	}

FileReader
创建读取流对象,和指定名称文件相关联。如果文件不存在,抛出FileNotFoundException.
其中colse方法不会刷新缓冲区;

对应缓冲类
BufferedWriter 特有方法newLine();
BufferedReader 特有方法readerLine();
import java.io.*;

class byteDemo 
{	
	public static void main(String[] args) 
	{
		FileInputStream is=null ;
		FileOutputStream os=null;
		try
		{
			is= new FileInputStream("tupian.gif");
			os= new FileOutputStream("tupian_copy.gif");
			byte[] buf= new byte[1024];
			int len=0;
			while((len=is.read(buf))!=-1)
			{
				os.write(buf,0,len);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("error");
		}
		finally
		{
			try
			{
				if(is!=null)
				is.close();
			}
			catch (IOException e)
			{
				System.out.print("失败");
			}
			try
			{
				if(os!=null)
				os.close();
			}
			catch (IOException e)
			{
				System.out.print("失败");
			}
		}
	}
}


MyBufferedReader
import java.io.*;
class myBuffer
{
	public static void main(String[] args)throws IOException
	{
		Buffered br = new Buffered(new FileReader("byteDemo.java"));
		 BufferedWriter bt = new BufferedWriter(new FileWriter("byteDemo_copy.txt"));
		String line = null;
		br.setNumber(100);
		while((line=br.myReadLine())!=null)
		{
			bt.write(line);
			bt.newLine();
			bt.flush();
		}
		bt.close();
		br.myClose();
	}
}
class Buffered
{
	private FileReader r;
	private int lineNumber;
	Buffered(FileReader r)
	{
		this.r=r;
	}
	public String myReadLine()throws IOException
	{
		lineNumber++;
		StringBuilder sb = new StringBuilder();
		int num=0;
		while((num=r.read())!=-1)
		{
			if(num=='\r')
				continue;
			if(num=='\n')
				return new String(lineNumber+":"+sb.toString());
			//else
			sb.append((char)num);
		}
		if(sb.length()!=0)
			return new String(lineNumber+":"+sb.toString());
	
			return null;
	}
	public void myClose()throws IOException
	{
		r.close();
	}
	public void setNumber(int n)
	{
		lineNumber=n;
	}
	public int getNumber()
	{
		return lineNumber;
	}
}

字节流
FileOutputStream
FileInputStream

转换流对象:
InputStreamReader
OutputStreamWriter

流对象的操作规律:
1,明确源和目的。
2,操作的数据是否为纯文本。
3,当体系明确后,在明确使用哪个具体的对象。通过设备来区分,源设备:内存,硬盘,键盘。目的设备:内存,硬盘,控制台。


资源分割。读取流读到资源。分别输出到若干个文件中。
资源拼接。
SequenceInputStream(Enumeration<? extends InputStream> e)
SequenceInputStream(InputStream s1, InputStream s2)
首先将需要拼接的输入流对象存到集合当中,然后为了得到 Enumeration对象。建立匿名对象覆盖其中的方法使其与集合相关联。
import java.io.*;
import java.util.*;
class SplitFile 
{
	public static void main(String[] args) throws IOException
	{

		//split();

		sequence();
	}
		//切割文件
		public static void split() throws IOException
		{
			FileInputStream fis = new FileInputStream("D:\\java\\test\\day07\\冰河世纪1.RMVB");
			FileOutputStream fos = new FileOutputStream("D:\\java\\test\\day07\\1.part");
			//定义缓冲区
			byte[] buf = new byte[1024*1024*10];
			int len = 0;
			int num = 1;
			long n =0;
			
			while((len=fis.read(buf))!=-1)
			{
				n++;
				fos.write(buf,0,len);
				if(n%10==0)
				{	
					fos.close();
					fos = new FileOutputStream("D:\\java\\test\\day07\\"+(++num)+".part");
				}
			}
			fis.close();
			fos.close();
	     }
		 //拼接文件
		public static void sequence()throws IOException
		{
			//SequenceInputStream sis = new SequenceInputStream();
			ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
			for(int x=1;x<6;x++)
			{
				al.add(new FileInputStream("D:\\java\\test\\day07\\"+x+".part"));
			}
			final Iterator<FileInputStream> it = al.iterator();
			Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
			{
				public  boolean hasMoreElements()
				{
					return it.hasNext();
				}
				public  FileInputStream nextElement()
				{
					return it.next();
				}
			};
			SequenceInputStream sis = new SequenceInputStream(en);
			FileOutputStream fos = new FileOutputStream("D:\\java\\test\\day07\\copy.rmvb");
			byte[] buf = new byte[1024*1024*10];
			int len = 0;
			while((len=sis.read(buf))!=-1)
			{
				fos.write(buf,0,len);
			}
			sis.close();
			fos.close();
		}
}

File:
将已有或者不存在的文件或者文件夹封装成文件对象。
File file=new File(pathname);
File file=new FIle(path,name);
常见方法:
1,创建:createNewFile();如果文件已经存在,则不创建返回false和输出流不同。
2,删除:delete();   deleteOnExit();退出时删除。
3,判断:canExecute() 是否是可执行文件。canRead(),canWrite(); exists()是否存在。mkdir()创建文件夹,创建一级目录。
mkdirs()创建多级目录。isFile(),isDirectory()。 isHidden()是否是隐藏的。isAbsolute()是否是绝对路径。
4,获取信息:getName();getPath(); getParent();返回的是绝对路径中的父目录。如果获取的是相对路径那么返回的是null。(getAbsolutePath();getAbsoluteFile();返回值不同可相互转换) lastModified();最后修改时间。length();
renameTo(),将一个文件改名,并按照路径放置文件。
目录里文件的递归例子
import java.io.*;
class FileDemo 
{
	public static void main(String[] args) 
	{
		File dir=new File("d:\\java");
		showDir(dir,0);
	}
	public static String getLevel(int level)
	{
		StringBuilder sb = new StringBuilder();
		for(int x=0;x<level;x++)
		{
			sb.append(" ");
		}
		return sb.toString();
	}
	public static void showDir(File dir,int level)
	{
		System.out.println(getLevel(level)+dir.getName());
		level++
		File[] files = dir.listFiles();
		for(int x=0;x<files.length;x++)
		{
			if(files[x].isDirectory())
				showDir(files[x]);
			else
				System.out.println(files[x]);
		}
	}
}
删除目录原理:在windows中,删除目录从里面往外面删除。所以使用递归。
import java.io.*;
class  RemoveDir
{
	public static void main(String[] args) 
	{
		File dir=new File("d:\\testdir");
		removeDir(dir);
	}
	public static void removeDir(File dir)
	{
		File[] files=dir.listFiles();
		for(int x=0;x<files.length;x++)
		{
			if(files[x].isDirectory())
				removeDir(files[x]);
			System.out.println(files[x].toString()+"file"+files[x].delete());
		}
		System.out.println(dir+":dir:"+dir.delete());
	}
}

listRoots()列出根盘符。
list()列出目录中的文件名。封装的对象必须是目录。该目录还必须存在。可以加入文件名过滤器。
FilenameFileter(){
public boolean accept(FIle dir,String name){
return name.endsWith(" ");
}
}

Properties对象:是hashtable的子类。也就是说它具备map集合的特点。而且他里面储存的键值都是字符串。
此对象可以直接和流向关联。
pro.load(is);
是集合中和IO技术想结合的集合容器;
该对象的特点:可以用于键值对形式的配置文件。固定格式键=值。
import java.io.*;
import java.util.*;
class zhuCeDemo //注册表练习
{
	public static void main(String[] args)throws IOException 
	{
		
		File file = new File("peizhi.ini");
		if(!file.exists())
			file.createNewFile();
		Properties  pro= new Properties();
		BufferedReader br = new BufferedReader(new FileReader(file));
		//读取文件
		pro.load(br);
		String value = pro.getProperty("time");
		int num=0;
		if(value!=null)
			num=Integer.parseInt(value);
		num++;
		if(num>=6)
		{
			System.out.print("error");
			return;
		}
		pro.setProperty("time",num+"");
		FileOutputStream fos = new FileOutputStream(file);
		pro.store(fos,"");//将Properties里的数据通过流写到文件中
		br.close();
		fos.close();
	}
}

对象的序列化:
ObjectInputStream和ObjectOutputStream
被操作的对象要实现Serializable(标记接口:无方法。);
可直接操作基本数据类型。将对象写到一个文件里去。将对象实例化存储。

管道流:
将输入输出管道流封装成2个对象。并且实现Runnable接口。
import java.io.*;
class Read implements Runnable 
{
	private PipedInputStream in;
	Read(PipedInputStream in)
	{
		this.in=in;
	}
	public void run()
	{
		try
		{
			byte[] buf = new byte[1024];
			int len=in.read(buf);
			String=new String(buf,0,len);
			System.out.println(s);
		}
		catch (IOException e)
		{
			throw new RuntimeException("管道读取流失败"); 
		}
	}
}
class Write implements Runnable
{
	private PipedOutputStream out;
	Write(PipedOutputStream out)
	{
		this.out=out;
	}
	public void run()
	{
		try
		{
			out.write("guandao".getBytes());
			out.close();
		}
		catch (IOException e)
		{
			throw new RuntimeException("管道输出流失败"); 
		}
	}
}
class PipedStreamDemo
{
	public static void main(String[] args)throws IOException
	{
	PipedInputStream in = new PipedInputStream();
	PipedOutputStream out = new PipedOutputStream();
	in.connect(out);
	new Thread(new Read(in)).start();
	new Thread(new Write(out)).start();
	}

}
RandomAccessFile:随机访问文件
不是IO体系中的子类,而是直接继承自Object,但是他是IO包中的成员,因为他具备读写功能,内部封装了一个数组,而且通过指针对数组的元素进行操作,可以通过getFilePointer获取指针的位置,同时可以通过seek改变指针的位置。
其实读写原理就是内部封装了字节输入和输出流。
通过构造函数可以看出该类只能操作文件。并且可以选择模式。
模式有4种:r只读方式打开,rw打开以便读写 rws对文件内容和元数据每个同步更新的都同步写入到底层设备。rwd只同步内容
如果模式为r,文件没有,不会创建文件。抛出异常。
如果模式为rw,文件不存在,创建文件,如果存在不会覆盖。
名字过长统一用多字节形式存储
import java.io.*;
class RandomAccessFileDemo 
{
	public static void main(String[] args)thorws IOException
	{
		readFile();
		//writeFile();
	}
	public static void writeFile()thorws IOException
	{
		RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");
		raf.write("java".getBytes());
		raf.writeInt(97);
		//raf。writeInt(97);默认写出最低8位一个字节
		raf.write("java1".getBytes());
		raf.writeInt(99);

		raf.close();
	}
	public static void readFile()thorws IOException
	{
		RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");
		raf.seek(8*1);//调整对象指针
		raf.write("java3".getBytes());//可在指定位置继续写入数据覆盖原数据
		raf.skipBytes(8);//跳过指定的字节,不能往回跳
		byte[] buf=new byte[4];
		raf.read(buf);
		String s=new String(buf);
		int age=raf.readInt();
		System.out.print(name+":"+age);
		raf.close();
	}
}

操作基本数据的流对象:
DataOutputStream与 DataInputStream
import java.io.*;
class DateStreamDemo 
{
	public static void main(String[] args)throws IOException
	{
		writeData();
		readData();
	}
	public static void readData()throws IOException
	{
		DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
		//注意:读取一定要数据类型按存储顺序读,否则数据错乱。
		int num=dis.readBoolean();
		boolean b=dis.readBoolean();
		double d=dis.readDouble();
		dis.close();
	}
	public void static void write()throws IOException
	{
		DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));
		dos.writeInt(230);
		dos.writeBoolean(true);
		dos.writeDouble(99.323);
		dos.close();
	}
	public static void writeUTFDemo()throws IOException
	{
		DataOutputStream dos=new DataOutputStream(new FileOutputStream("UTF.txt"));
		//通过UTF-8的编码形式写出数据。2格子8字节。只能用readUTF()读取
		dos.writeUTF("你好");
		dos.close();
	}

}
操作字节数组:
ByteArrayInputStream与 ByteArrayOutputStream
ByteArrayInputStream:在构造的时候,需要接收数据源,而且数据源是一个字节数组。
ByteArrayOutputStream:在构造的时候,不用定义数据目的,因为对象中已经封装了可变长度的字节数组,这就是数据目的
因为这两个流对象都操作的是数组,并没有使用系统底层资源。所谓不需要使用close关闭
import java.io.*;
class  ByteArrayStream
{
	public static void main(String[] args) 
	{
		//数据源
		ByteArrayInputStream bis =new ByteArrayInputStream("abcd".getBytes());
		//数据目的
		ByteArrayOutputStream bos=new ByteArrayInputStream();
		int by=0;
		while((by=bis.read())!-1)
		{
			bos.write(by);
		}
		System.out.print(bos.size()+":"bos.toString);
	}
}
操作字符数组:
CharArrayReader与 CharArrayWriter
操作字符串:
StringReader与StringWriter


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值