黑马程序员——I/O(输入/输出)流

-------  android培训 java培训 、期待与您交流! ----------
Java的输入/输出流
       对于任何编程语言,除了数据的输入输出操作都是极其重要的,而在Java语言中是以输入输出流的形式进行数据的输入输出处理。
       数据的输入:程序从数据源读取数据的过程;
       数据的输出:程序将数据写入目标设备。
       文件:输入输出经常处理的设备之一
I/O流它是用于设备之间的数据传输用的,它按照数据流向分为输入流,输出流。
按照操作类型分为俩种: 字节流,以字节形式进行数据传输; 字符流,以字符形式进行数据传输。
IO流常用父类:
字节流的抽象父类:InputStream、OutputStream
字符流的抽象父类:Reader、Writer
IO使用程序前,要导入IO包中的类,使用时,进行IO异常处理,使用后关闭,关闭流
常用方法:InputSteam:ready()读取一个节;
read(byte[])读取若干(数组长度)字节;
available()获取可读的字节数
close()关闭流,释放资源
OutputStream:
write(int) 写出一个字节
write(byte[])写出数组中所有字节
write(byte[],start,len)
close() 关闭流,释放资源
转换流 :InputStreamReader
键盘录入 :BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
  写入转换流 :    OutPutStreamWriter
控制台输出 :BufferedWriter buwr=new BufferedWriter(new OutputStreamWriter(System.out));
上面可以通过 System.setIn 和 System.setOut 来设置对应的源和目的 。
  转换流什么时候用 : 字符和字节之间的桥梁 , 通常波及到编码转换时要用到转换流 。
流操作的基本规律 :
1、明确源和目的;
2、操作的数据是否是纯文本 ;
3、当体系明确后 , 在明确要使用哪个具体对象 . 是否要提高效率 . 来加入转换流 .;
I/O 包 File 类是文件和目录路径名的抽象表示形式。
用来将文件或者文件夹封闭成对象 , 方便对文件与文件夹的属性信息进行操作 。
File 对象可以作为参数传递给流的构造函数 。
separator 字段是目录分隔符 。
File f=new File(“aa.txt”);// 将 aa.txt 封闭成 file 对象 ,可以将已有的和末出现的文件夹封装成对象 。
File f2=new File(“c:\\ab”,”bc.txt”);//”bc.txt” 可以传一个可变的参数 。
syso(f);// 打印文件的路径 ,,按封装时的格式打印出来 。
  • InputStream:
/*
线程间通讯:
其实就是多个线程在操作同一个资源,
但是操作的动作不同。
 */
class Res
{
	String name;
	String sex;
	boolean flag = false;
}

class Input implements Runnable
{
	private Res r ;
	Input(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		int x = 0;
		while(true)
		{
			synchronized(r)
			{

				if(r.flag)
					try{r.wait();}catch(Exception e){}
				if(x==0)
				{
					r.name="mike";
					r.sex="man";
				}
				else
				{
					r.name="丽丽";
					r.sex = "女女女女女";
				}
				x = (x+1)%2;
				r.flag = true;
				r.notify();
			}
		}
	}
}

class Output implements Runnable
{
	private Res r ;

	Output(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			synchronized(r)
			{
				if(!r.flag)
					try{r.wait();}catch(Exception e){}
				System.out.println(r.name+"...."+r.sex);
				r.flag = false;
				r.notify();
			}
		}
	}
}

class  InputOutputDemo
{
	public static void main(String[] args) 
	{
		Res r = new Res();

		Input in = new Input(r);
		Output out = new Output(r);

		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);

		t1.start();
		t2.start();
	}
}

//notifyAll();

/*
wait:
notify();
notifyAll();

都使用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法要定义Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁,
只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。
不可以对不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁。

而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。
 */

  • OutputStream
/*
线程间通讯:
其实就是多个线程在操作同一个资源,
但是操作的动作不同。
 */
class Res
{
	private String name;
	private String sex;
	private boolean flag = false;

	public synchronized void set(String name,String sex)
	{
		if(flag)
			try{this.wait();}catch(Exception e){}
		this.name = name;

		this.sex = sex;
		flag = true;
		this.notify();
	}
	public synchronized void out()
	{
		if(!flag)
			try{this.wait();}catch(Exception e){}
		System.out.println(name+"........"+sex);
		flag = false;
		this.notify();
	}
}

class Input implements Runnable
{
	private Res r ;
	Input(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		int x = 0;
		while(true)
		{
			if(x==0)				
				r.set("mike","man");				
			else	
				r.set("丽丽","女女女女女");				
			x = (x+1)%2;
		}
	}
}

class Output implements Runnable
{
	private Res r ;

	Output(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			r.out();
		}
	}
}

class  InputOutputDemo2
{
	public static void main(String[] args) 
	{
		Res r = new Res();

		new Thread(new Input(r)).start();
		new Thread(new Output(r)).start();
		/*
		Input in = new Input(r);
		Output out = new Output(r);

		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);

		t1.start();
		t2.start();
		 */
	}
}

File 常见方法 .
1、 创建 boolean  createNewFile();
2、 删除 boolean delete();  void deleteOnExit();  mkdir();  new File(“abc\\kk”).mkdir();
mkdirs(); 创建多级文件夹 。
3、判断        Boolean   exists(); 文件是否存在 。
isDirectory();isFile(); 通过这两方法可以判断封装完的对象是什么 ?
4、获取信息 .getXXX();
拷贝文件有4种方式, 逐个字节拷贝  不建议使用效率太低, 自定义数组拷贝 建议使用,不大不小的数组效率高。
定义一个大数组拷贝,数组和文件的字节个数一样大 不建议使用,可能会造成内存溢出, 带缓冲区的拷贝 建议使用 带缓冲区, 一次读取多个字节装入缓冲区。效率高 。
  finally嵌套:
1.6版本及以前的标准的异常处理代
 
FileInputStream fis = null; 
FileOutputStream fos = null; 
      try {
          fis = new FileInputStream("aaa.txt");
fos = new FileOutputStream("bbb.txt");
                       int b;
            while((b = fis.read()) != -1) {
                 fos.write(b);
             }
         }finally {
            try {
                 if(fis != null) 
                     fis.close();
             } finally {
                 if(fos != null)
                     fos.close();
             }
         }
try close

1.7版本的标准的异常处理代码:
 try(
            FileInputStream fis = new FileInputStream("aaa.txt");
            FileOutputStream fos = new FileOutputStream("bbb.txt");
            MyClose mc = new MyClose();
        ){
            int b;
            while((b = fis.read()) != -1) {
                fos.write(b);
            }
        }

  • StringBuffer是字符串缓冲区:
ArrayListTest

/*
StringBuffer是字符串缓冲区。是一个容器。
特点:
1,长度是可变化的。
2,可以字节操作多个数据类型。
3,最终会通过toString方法变成字符串。

C create U update R read D delete

1,存储。
	StringBuffer append():将指定数据作为参数添加到已有数据结尾处。
	StringBuffer insert(index,数据):可以将数据插入到指定index位置。

2,删除。
	StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end。
	StringBuffer deleteCharAt(index):删除指定位置的字符。

3,获取。
	char charAt(int index) 
	int indexOf(String str) 
	int lastIndexOf(String str) 
	int length() 
	String substring(int start, int end) 

4,修改。
	StringBuffer replace(start,end,string);
	void setCharAt(int index, char ch) ;

5,反转。
	StringBuffer reverse();

6,将缓冲区中指定数据存储到指定字符数组中。
	void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 

JDK1.5 版本之后出现了StringBuilder.

StringBuffer是线程同步。
StringBuilder是线程不同步。

以后开发,建议使用StringBuilder

升级三个因素:
1,提高效率。
2,简化书写。
3,提高安全性。
 */
class Demo{}

class StringBufferDemo 
{
	public static void main(String[] args) 
	{
		//method_update();

		StringBuilder sb = new StringBuilder("abcdef");

		char[] chs = new char[6];

		sb.getChars(1,4,chs,1);//将

		for(int x=0; x<chs.length; x++)
		{
			sop("chs["+x+"]="+chs[x]+";");
		}

		draw(3,6);
		draw(8,9);

		//		StringBuilder sb1 = new StringBuilder();
		//		sb1.append(new Demo()).append(new Demo());
		//		sop("sb1="+sb1);
	}
	public static void method_update()
	{
		StringBuffer sb  = new StringBuffer("abcde");

		//		sb.replace(1,4,"java");
		sb.setCharAt(2,'k');

		sop(sb.toString());

	}
	public static void method_del()
	{
		StringBuffer sb  = new StringBuffer("abcde");

		//		sb.delete(1,3);
		//清空缓冲区。
		//sb.delete(0,sb.length());

		//sb.delete(2,3);
		sb.deleteCharAt(2);

		sop(sb.toString());
	}

	public static void method_add()
	{
		StringBuffer sb = new StringBuffer();

		//sb.append("abc").append(true).append(34);
		//		StringBuffer sb1 = sb.append(34);
		//		sop("sb==sb1:"+(sb==sb1));

		sb.insert(1,"qq");
		sop(sb.toString());//abctrue34
		//sop(sb1.toString());

	}

	public static void sop(String str)
	{
		System.out.println(str);
	}

	public static void draw(int row,int col)
	{
		StringBuilder sb = new StringBuilder();
		for(int x=0; x<row; x++)
		{
			for(int y=0; y<col; y++)
			{
				sb.append("*");
			}
			sb.append("\r\n");
		}

		sop(sb.toString());
	}

}

  • ArrayListTest:

import java.util.*;

/*
去除ArrayList集合中的重复元素。
*/

class ArrayListTest 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		ArrayList al = new ArrayList();

		al.add("java01");
		al.add("java02");
		al.add("java01");
		al.add("java02");
		al.add("java01");
		//		al.add("java03");

		/*
		在迭代时循环中next调用一次,就要hasNext判断一次。
		Iterator it = al.iterator();

		while(it.hasNext())
		{
			sop(it.next()+"...."+it.next());
		}
		 */

		/**/
		sop(al);

		al = singleElement(al);

		sop(al);
	}

	public static ArrayList singleElement(ArrayList al)
	{
		//定义一个临时容器。
		ArrayList newAl = new ArrayList();

		Iterator it = al.iterator();

		while(it.hasNext())
		{
			Object obj = it.next();

			if(!newAl.contains(obj))
				newAl.add(obj);
		}
		return newAl;
	}
}


  • Collection:

import java.util.*;

/*
Collection定义了集合框架的共性功能。
1,添加
	add(e);
	addAll(collection);

2,删除
	remove(e);
	removeAll(collection);
	clear();

3,判断。
	contains(e);
	isEmpty();

4,获取
	iterator();
	size();

5,获取交集。
	retainAll();

6,集合变数组。
	toArray();

1,add方法的参数类型是Object。以便于接收任意类型对象。

2,集合中存储的都是对象的引用(地址)
什么是迭代器呢?
其实就是集合的取出元素的方式。
如同抓娃娃游戏机中的夹子。

迭代器是取出方式,会直接访问集合中的元素。
所以将迭代器通过内部类的形式来进行描述。
通过容器的iterator()方法获取该内部类的对象。
*/
class  CollectionDemo
{
	public static void main(String[] args) 
	{
		method_get();
	}
	public static void method_get()
	{
		ArrayList al = new ArrayList();

		//1,添加元素。
		al.add("java01");//add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");

		/*
		Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素。

		while(it.hasNext())
		{
			sop(it.next());
		}
		 */

		for(Iterator it = al.iterator(); it.hasNext() ; )
		{
			sop(it.next());
		}
	}

	public static void method_2()
	{
		ArrayList al1 = new ArrayList();

		al1.add("java01");
		al1.add("java02");
		al1.add("java03");
		al1.add("java04");
		ArrayList al2 = new ArrayList();

		al2.add("java03");
		al2.add("java04");
		al2.add("java05");
		al2.add("java06");

		//al1.retainAll(al2);//去交集,al1中只会保留和al2中相同的元素。
		al1.removeAll(al2);

		sop("al1:"+al1);
		sop("al2:"+al2);
	}

	public static void base_method()
	{
		//创建一个集合容器。使用Collection接口的子类。ArrayList
		ArrayList al = new ArrayList();

		//1,添加元素。
		al.add("java01");//add(Object obj);
		al.add("java02");
		al.add("java03");
		al.add("java04");

		//打印原集合。
		sop("原集合:"+al);

		//3,删除元素。
		//al.remove("java02");
		//al.clear();//清空集合。

		//4,判断元素。
		sop("java03是否存在:"+al.contains("java03"));
		sop("集合是否为空?"+al.isEmpty());

		//2,获取个数。集合长度。
		sop("size:"+al.size());

		//打印改变后的集合。
		sop(al);
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}






        -------  android培训 java培训 、期待与您交流! ----------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值