黑马程序员_毕向东_Java基础_DAY19_字节流、转换流、小知识点

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

字节流:

基础概念:

字节流的两个抽象基类:

OutputStream

InputSteam

 

OutputStream类:

java.lang.Object

 java.io.OutputStream

 

构造器:

OutputStream()

 

方法:

 voidclose()

         关闭此输出流并释放与此流有关的所有系统资源。

 voidflush()

          刷新此输出流并强制写出所有缓冲的输出字节。

 voidwrite(byte[] b)

         将 b.length 个字节从指定的 byte 数组写入此输出流。

 voidwrite(byte[] b, int off, int len)

         将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

abstract void write(int b)

         将指定的字节写入此输出流。

 

注意:

字节流只能操作int、字节数组,不能操作char[]和String。

 

子类:

FileOutputStream

直接对字节流进行操作,不需要flush,每获取一个字节,就存入到目标当中。

FileOutputStream output = newFileOutputStream("demo.txt");

output.write("abcde".getBytes());//使用getBytes方法将字符串转换为字节数组

 

FileInputStream

具有一个特有方法:

available(),可以返回文件的字节数。

FileInputStream fis = newFileInputStream("源文件.txt");

byte buf = new byte[fis.available()];

 

使用字节流复制图片文件:

import java.io.*;

class  CopyPicture
{
	public static void main(String[] args) 
	{
		BufferedInputStream fis = null;
		BufferedOutputStream fos = null;
		try
		{
			fis = new BufferedInputStream(new FileInputStream("error.jpg"));
			fos = new BufferedOutputStream(new FileOutputStream("error_buffcopy.jpg"));
			int b = 0;
			while((b = fis.read()) != -1){
				fos.write(b);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("图片复制错误");
		}
		finally{
			try
			{
				if(fis != null)
					fis.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("文件字节输入流关闭错误");
			}
			try
			{
				if(fos != null)
					fos.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("文件字节输出流关闭错误");
			}
		}
	}
}
 

字节流的缓冲区:

字节流的缓冲区使用的是:

BufferedInputStream / BufferedOutputStream

在使用上与字符流的缓冲区类似。

使用自定义类模拟字节缓冲流:

import java.io.*;
 
class MyBufferedInputStream extendsInputStream{
       privateInputStream is;
       privateint pos = 0;
       privateint count = 0;
       privatebyte[] buff = new byte[1024 * 1024];
 
       publicMyBufferedInputStream(InputStream is){
              this.is= is;
       }
 
       publicint read() throws IOException{
              if(count== 0){           
                     count= is.read(buff);
                     if(count< 0)
                            return-1;
                     pos= 0;
                     count--;
                     returnbuff[pos++] & 255;
              }
              elseif(count > 0){
                     count--;
                     returnbuff[pos++] & 255;
              }
              return-1;
       }
 
       //测试MyBufferedInputStream,拷贝MP3
       publicstatic void main(String[] args){
              MyBufferedInputStreammyin = null;
              BufferedOutputStreambos = null;
              try{
                     myin= new MyBufferedInputStream(new FileInputStream("加州旅馆---老鹰乐队.mp3"));
                     bos= new BufferedOutputStream(new FileOutputStream("加州旅馆---老鹰乐队_copy.mp3"));
                     intby = 0;
                     while((by= myin.read()) != -1){
                            bos.write(by);
                     }
              }
              catch(IOException e){
                     thrownew RuntimeException("mp3文件复制错误");
              }
              finally{
                     if(myin!= null){
                            try{
                                   myin.close();
                            }
                            catch(IOException e){
                                   thrownew RuntimeException("读入流关闭错误");
                            }
                     }
                     if(bos!= null){
                            try{
                                   bos.close();
                            }
                            catch(IOException e){
                                   thrownew RuntimeException("输出流关闭错误");
                            }
                     }
              }
       }
}


 

转换流:

自定义类读取键盘录入:

使用System.in来获取与键盘录入关联的InputStream对象。

通过调用此对象的read方法可以获取从键盘录入的第一个字符。

如果想要一次读取一行,可以自定义一个与BufferedReader类的readLine方法类似的方法。

使用StringBuilder作为临时缓冲,然后利用while(true)来循环读取,读到普通字符时append进缓冲区,当读到\r\n时,判断是否录入的是结束符,如果是,退出循环,如果不是打印缓冲区中的数据,并清空缓冲区。

 

利用转换流来读取键盘录入:

事实上读一行的方法已经存在于BufferedReader方法中了。

因此我们可以简单的使用BufferedReader中的readLine方法即可。

但是,BufferedReader读取的是字符流,但是System.in却是一个字节流。这时就需要利用转换流InputStreamReader来将字节流转换为字符流。

InputStreamReader isr = newInputStreamReader(System.in);
BufferedReader br = newBufferedReader(isr);
while(true){
       Strings = br.readLine();
       if("over".equals(s))
              break;
       System.out.println(s);
}


 

练习:

//将控制台输入的字符串存储到文件中,并改变编码形式
 
import java.io.*;
 
class IOChange
{
       publicstatic void main(String[] args)
       {
              BufferedReaderbr = null;
              BufferedWriterbw = null;
              try
              {
                     br= new BufferedReader(new InputStreamReader(System.in));
                     bw= new BufferedWriter(new OutputStreamWriter(newFileOutputStream("iochange.txt"), "UTF-8"));
                     while(true){
                            Strings = br.readLine();
                            if("over".equals(s))
                                   break;
                            bw.write(s);
                            bw.newLine();
                            bw.flush();
                     }
              }
              catch(IOException e)
              {
                     thrownew RuntimeException("信息录入错误");
              }
              finally{
                     if(br!= null){
                            try
                            {
                                   br.close();
                            }
                            catch(IOException e)
                            {
                                   thrownew RuntimeException("输入流关闭错误");
                            }
                     }
                     if(bw!= null){
                            try
                            {
                                   bw.close();
                            }
                            catch(IOException e)
                            {
                                   thrownew RuntimeException("输出流关闭错误");
                            }
                     }
              }
       }
}
 

流操作的基本规律:

流对象有很多,不知道该用哪一个时怎么办?

 

通过三个明确来完成:

1.明确源和目的

       源:输入流--InputStream / Reader

       目的:输出流 -- OutputStream / Writer

2.操作的数据是否是纯文本。

       纯文本:字符流

       非文本:字节流

 

3.当体系明确后,再明确要使用哪个具体的对象。

   通过设备来区分:

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

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

 

转换流什么时候使用:

1.     字符和字节之间的桥梁。

2.     涉及到字符编码转换时需要用到转换流。

 

小知识点:

改变标准输入输出设备:

使用System类中的static方法:

static void setIn(InputStream in)

static void setOut(PrintStreamout)

 

异常日志信息:

import java.io.*; 
import java.util.*; 
import java.text.*; 
class ExceptionInfo 
{ 
    public static void main(String[] args) 
    { 
         try 
         { 
               int[] arr = new int[2]; 
               System.out.println(arr[3]); 
         } 
         catch (Exception e) 
         { 
               try 
               { 
                    Date d = new Date(); 
                    SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
                    String s =sdf.format(d); 
                    PrintStream ps = newPrintStream("exception.log"); 
                    ps.println(s); 
                    System.setOut(ps);                    
               } 
               catch (IOException ie) 
               { 
                    throw newRuntimeException("创建日志文件失败"); 
               } 
              e.printStackTrace(System.out); 
         } 
    } 
} 


保留异常日志信息是以后开发中可能经常需要做的事儿,对此可以使用 网上提供的用于java异常信息存储的包--- log4j。


你可能感兴趣的:(黑马自学课程)