黑马程序员 总结(十八)——I/O流(字节流)

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

字节流——OutputStream和InputStream

 一、FileOutputStream

1、简介:文件输出流是用于将数据写入 FileFileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。FileOutputStream 用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用FileWriter

2、构造方法:

1、FileOutputStream(File file):根据给定的 File 对象构造一个FileOutputStream对象。

2、FileOutputStream(File file, boolean append) :根据给定的 File 对象构造一个 FileOutputStream对象,当append为true为真时,则是在给定的File对象后面添加。

3、FileOutputStream(FileDescriptor fd) :构造与某个文件描述符相关联的FileOutputStream对象

4、FileOutputStream(String fileName) :根据给定的文件名构造一个FileOutputStream对象

5、FileOutputStream(String fileName, boolean append):根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileOutputStream 对象。

3、字节流的写入:

1、导入java.io包。

2、创建一个FileOutputStream(写入字符流)对象,该对象只有自己特有的构造方法用于创建对象。在创建该对象时必须指定要操作的文件。该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。实际上该步就是在明确操作的对象。

3、调用public void write()方法,将要写入的数据写入到流中。

4、如果是最后一次写入数据,则可以public void close()方法,将流中的数据刷到目标文件中,并且在刷新后关闭该流。

注:在建立写入字节流对象,操作完成后必须调用close方法关闭流对象。在字节流的写入和字符流有所不同。字节流写入是直接写入到目标文件,而不用flush()操作。

二、FileInputStream

1、简介:从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。FileInputStream 用于读取诸如图像数据之类的原始字节流。

2、构造方法:

1、FileInputStream(File file)  :在给定从中读取数据的File 的情况下创建一个新FileInputStream

2、FileInputStream(FileDescriptor fd):在给定从中读取数据的FileDescriptor 的情况下创建一个新FileInputStream

3、FileInputStream(String fileName) :在给定从中读取数据的文件名的情况下创建一个新FileInputStream

3、文件的读取:通过InputStream中的read()方法,以及它的重载方法。

三、图像文件的拷贝:

1、将I:\\Important\\IMG_0002.jpg文件拷贝是d盘的根目录下。

代码示例:

import java.io.*;
class  CopyPic
{
	public static void main(String[] args) throws IOException
	{
		FileOutputStream fo = new FileOutputStream("d:\\IMG_0002.jp");
		FileInputStream fi = new FileInputStream("I:\\Important\\IMG_0002.jpg");

		byte[] buf = new byte[1024];

		for (int flag=fi.read(buf);flag!=-1 ;flag=fi.read(buf) )
		{
			fo.write(buf,0,flag);
		}
	}
}

四、字节流的缓冲区:

1、原理:和字符流缓冲区的原理是一样的。

代码:

import java.io.*;
class  CopyMp3
{
	public static void main(String[] args) throws IOException
	{
		long start = System.currentTimeMillis();
		copy_mp3();
		long end = System.currentTimeMillis();
		System.out.println("复制完成,用时:"+(end-start)+"毫秒");
	}

		public static void copy_mp3()throws IOException
		{
			BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream("d:\\1\\混合1.mp3",true));
			BufferedInputStream bi = new BufferedInputStream(new FileInputStream("D:\\BaiDuMusic\\风儿啊!请你停下来.mp3"));
			
			for (int flag=bi.read();flag!=-1 ;flag=bi.read() )
			{
				bo.write(flag);
			}
		}
}
2、缓冲区对字节处理的一些技巧:

1、字节流的读取是读取一个字节(8个二进制位),当这个字节的八个位都为1的时候,计算机就会认为是-1。为了解决这个问题,就把这个读取的一个字节用int类型进行接收。为了使八位二进制数表示的是正数,则在返回的这个字节低八位为int数的低八位,其余的加0;方法是return byte&255;

2、当将byte提升为int类型后,1个字节变成了4歌字节,则是原文件增加了4倍。因此在Writer方法中又将此数据进行强转,使之仍然是八个位。


3、简易缓冲区定义的代码:

import java.io.*;

class MyBufferedInputStream
{
	private InputStream in;

	private byte[] buf = new byte[1024*4];
		
	private int pos = 0,count = 0;
	
	MyBufferedInputStream(InputStream in)
	{
		this.in = in;
	}

	//一次读一个字节,从缓冲区(字节数组)获取。
	public int myRead()throws IOException
	{
		//通过in对象读取硬盘上数据,并存储buf中。
		if(count==0)
		{
			count = in.read(buf);
			if(count<0)
				return -1;
			pos = 0;
			byte b = buf[pos];

			count--;
			pos++;
			return b&255;
		}
		else if(count>0)
		{
			byte b = buf[pos];

			count--;
			pos++;
			return b&0xff;
		}
		return -1;

	}
	public void myClose()throws IOException
	{
		in.close();
	}
}


键盘录入、转换流(设定指定字符集)
一、从键盘录入字符
1、原理:之前我 们处理的数据的时候都是先建立和文件相关的流。那怎么从处理从键盘输入的数据呢?
处理原理都是一样的,唯一不同的是我们之前要建立相关的流去读取原文件,现在的流是从键盘的录入读取而已。即用System,in;去代替原来的输入流对象。
2、 从键盘输入流的建立: InputStream in = System.in;通过前面学过的System类去建立这个对象。
3、 处理
1、处理方式和原来处理的方式一样。
2、代码:

import java.io.*;
class ReadIn
{
	public static void main(String[] args) throws IOException
	{
		//建立从键盘输入的流
		InputStream in = System.in;
		//建立键盘输入的字符串的存储区
		StringBuilder sb = new StringBuilder();
		//建立流对象输出的对象流
		BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\gh\\aba.txt",true));
		//读取从键盘输入的数据
		for (int flag=in.read();flag!=-1 ;flag=in.read() )
		{
			if (flag=='\r')
			{
				if (in.read()=='\n')
				{
					String s = sb.toString();
					//处理方式一:将从键盘输入的数据在屏幕上打印输出
					System.out.println(s);
					//处理方式二:把从键盘输入的数据分行的存在文本文件中
					bw.write(s);
					bw.newLine();
					bw.flush();
					//判断是否该结束循环条件一
					if ("over".equals(s))
					{
						break;
					}
					//判断是否结束循环的条件二
					String sb1 = sb.substring((sb.length()-4),sb.length());
					sb.delete(0,sb.length());
					if("over".equals(sb1))
						break;
					
				}
				//暂存从键盘输入的数据
				else
				{
					sb.append((char)'\r');
					sb.append((char)flag);
				}
			}
			else
			{
				sb.append((char)flag);
			}
		}
		//关闭流
		bw.close();
		in.close();
	}
}

二、转换流——InputStreamReader:

1、简介:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集

2、作用:在上面获取从键盘上键入的数据时我们只能一个一个的获取,我们还可以用通过转换流。将这个字节输入流转化成字符输入流。使之能读取一行的数据。

3InputStreamReader的使用:

1、建立字节输入流。

2、通过InputStreamReader的构造函数,将字节流输入流传入InputStreamReader中。

3、此时的使用和字符输入流一样。

4、代码示例:

要求:1、将从键盘输入的字符使用字符流的操作将其存贮在文本文件中

代码:

import java.io.*;
class ReadIn1
{
	public static void main(String[] args) throws IOException
	{
		//建立从键盘输入的流
		InputStream in = System.in;
		//建立字符输入缓冲流和字符输出缓冲流
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\1\\InputStreamReader.txt",true));
		//建立流对象输出的对象流
		for (String s=br.readLine(); s!=null; s=br.readLine())
		{
			bw.write(s);
			bw.newLine();
			bw.flush();
			
			//定义结束的条件
			if (s.length()>=4)
			{
				String s1 = s.substring(s.length()-4,s.length());
				if ("over".equals(s)||"over".equals(s1))
				{
					break;
				}
			}
			
		}

	}
}


三、转换流——OutputStreamWriter

1、简介:OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。

2、作用:将输出流转化成操作字符的输出流对象。

3、OutputStreamWriter的使用:

1、建立字节输入流。

2、通过InputStreamWriter的构造函数,将字节流输入流传入InputStreamWriter中。

3、此时的使用和字符输出流一样。

4、示例:

目的:把从键盘录入的数据保存在文本文件里。

   当末尾以over字符串结束则停止录入

代码:


import java.io.*;
class KeyBoard
{
	public static void main(String[] args) throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\1\\hm1.txt"));
		BufferedWriter bw1 = new BufferedWriter(new OutputStreamWriter(System.out));
		
		for (String s = br.readLine(); s!=null; s=br.readLine())
		{
			bw.write(s);
			bw.newLine();
			bw.flush();
			bw1.write(s);
			bw1.newLine();
			bw1.flush();
			if (s.length()>=4)
			{
				String s1=s.substring(s.length()-4,s.length());
					if ("over".equals(s1))
					{
						break;
					}
			}

		}
		br.close();
		bw.close();
		bw1.close();
	}
}

四、流对象操作规律

1、明确源和目的

源:输入流——>用InputStream、Reader

目的:输出流——>用OutputStream、Writer

2、操作数据是否是纯文本

是——>用字符流

不是——>用字节流

3、明确要使用的具体对象

通过设备来进行区分

源设备:内存、硬盘、键盘

目的设备:内存、硬盘、控制台

4、例如:拷贝一个纯文本文件。

明确源:为文件(使用读取流)——>为纯文本(用字符读取流)——>能操作文件的对象(FIieReader)

明确目的:写在硬盘上(写入流)——>文本(字符写入流)——>能操作文件的对象(FileWriter)

明确是否需要优化:要——>建立该流的缓冲对象,通过该对象去操作。

5、字节流到字符流的转换

如果字节流操作的是文本文件的时候我们可以通过OutputStreamWriter和InputStreamReader将其转换成字符流进行操作。

InputStreamReader类

InputStreamReader通过构造方法将字节流转换为字符流。并且在转换的时候可以制定编码表,如一个以UTF-8编码的文本文档,必须通过指定编码表才能将其打开。转换后的操作与操作字符流一样

6、改变标准输入输出设备:

在System类中提供了改变标准输入输出的方法。

setIn(InputStream in):将标准的输入设备设置成我们需要的设备。即改变System.in的对象。默认是键盘输入。

setOut(OutputStream out):将标准的输出设备设置成我们需要的设备。即改变System.out的对象。默认是答应在控制台。

7、异常的日志信息

1、在异常类中异常信息通过printStackTrace() 方法将信息打印在控制台上。这个方法实际是在执行printStackTrace(System.out)将异常信息输出在标准输出设备上。所以我们通过System类中提过的改变标准输出设备 的方法使之将该信息记录在文本文件中。当然也可以新建一个printedStream("a.txt")对象,去替代System.out对象。

2、打印异常的时间

建立util包中的Date对象,在通过text包中的SimpleDateFormat将时间格式化。

3、也可以通过log4j这个包建立日志信息。

4、示例:

import java.io.*;
import java.util.*;
import java.text.*;
class  ExceptionInfo
{
	public static void main(String[] args)throws IOException 
	{
		try
		{
			int[] arr = new int[2];
			System.out.println(arr[3]);
		}
		catch (Exception e)
		{
			
			try
			{
				Date d = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String s = sdf.format(d);

				PrintStream ps = new PrintStream("exeception.log");
				ps.println(s);
				System.setOut(ps);

				
			}
			catch (IOException ex)
			{
				throw new RuntimeException("日志文件创建失败");
			}
			e.printStackTrace(System.out);
		}
	}
}


8、Propertites中方法与流相结合

该类中有一个方法void list(PrintStream out):将属性列表输出到指定的输出流。即我们可以通过System类中getProperties()方法获取系统属性信息,然后利用list方法将其答应,或者通过list方法将其记录在文件中。

示例:

import java.util.*;
import java.io.*;
class  SystemInfo
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = System.getProperties();

		//System.out.println(prop);
		prop.list(new PrintStream("sysinfo.txt"));
	}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值