Java进击(二) I/O流

时间:2023-02-17 17:00:02



          流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样。

        我们可以把输入输出流从以下几个方面分类:

  1)输入流或输出流(从流的方向划分)

  2)节点流或处理流(从流的分工划分)

  3)面向字符的流或面向字节的流(从流的内容划分)

 

图:

                                     Java进击(二) I/O流    Java进击(二) I/O流


1.面字符的流----ReaderWriter

       

          字符流的源或目标通常是文本文件。字符流可以实现Java程序中的内部格式和文本文件、显示输出、键盘输入等外部格式之间的转换。ReaderWriterjava.io包中所有字符流的抽象基类。ReaderWriter的子类又可以分为两大类:节点流、处理流。蓝色为节点流;空白色为处理流。

                                                 Java进击(二) I/O流Java进击(二) I/O流

                                             Java进击(二) I/O流


  使用例子:

                   1)读取文本文件

                    代码:

				import java.io.*;
				class Reader{
				   public static void main(String[] args)
				   {
				      String fileName="D:/java/Hello.txt";
					  String line;
					  try{
					      //创建文件输入流并放入缓冲流中
						  BufferedReader in=new BufferedReader(new FileReader(fileName));
						  line =in.readLine();//读取一行内容
						 while((c=in.read())!=-1)	  
								  {
								     System.out.print((char)c);
									 
								  }
						  in.close();//关闭缓冲流,文件输入流自动也被关闭
					  }
					  catch(IOException iox)//如果出现异常则处理
					  {
					     System.out.println("Problem reading"+fileName);
					  }
				   
				   }
				}
                    运行结果如下:

                                                                                Java进击(二) I/O流


                 (2)写文本文件

				import java.io.*;
				class Write{
				   public static void main(String[] args)throws IOException
				   {
				       String fileName = "D:/java/HelloWorld.txt";
					   FileWriter writer=new FileWriter(fileName);//创建一个给定文件名的输出流对象
					   writer.write("Hello you one \n");//往流里写字符数组
					   writer.write("This is my hello world, \n");
					   writer.write("How do you think about it? \n");
					   writer.write("我也可以输入中文\n");
					   writer.close();//关闭流
					   
				   }
				}

                     运行结果:

                             Java进击(二) I/O流


2.面向字节的流---InputStreamOutputStream

          

            这种流通常用来读写诸如图片、声音之类的二进制数据。ObjectInputStreamObjectOutputStream可以用来读、写对象;PipedInputStreamPipedOutputStream用来完成线程之间的通信;蓝色为节点流、透明为处理流。

                                                                Java进击(二) I/O流

                                                         Java进击(二) I/O流Java进击(二) I/O流

                                                             Java进击(二) I/O流


             使用例子:

                           (1)写二进制文件:

					import java.io.*;
					class Writebyte{
					   public static void main(String[] args){
					       String fileName="D:/data1.dat";
						   int value0 = 255, value1 = 0, value2 = -1;
						   try{
						   //将DataOutputStream与FileOutputStream连接可输出不同类型的数据
						      DataOutputStream out=new DataOutputStream(new FileOutputStream(fileName));
							  out.writeInt(value0);
							  out.writeInt(value1);
							  out.writeInt(value2);
							  out.close();
						   }
						   catch(IOException iox){
						      System.out.println("Problem writing"+ fileName);
						   }
					   }
					}

                         (2)读二进制文件:

					import java.io.*;
					class Readbyte{
					   public static void main(String[] args){
					       String fileName="D:/data1.dat";
						   int sum = 0;
						   try{
						       DataInputStream instr = new DataInputStream(new BufferedInputStream(new FileInputStream(fileName)));
							   sum +=instr.readInt();
							   sum +=instr.readInt();
							   sum +=instr.readInt();
							   System.out.println("The sum is "+sum);
							   instr.close();
						   }
						   catch(IOException iox){
						       System.out.println("Problem reading"+fileName);
						   }
					   }
					}

                                  运行结果:

                                                        Java进击(二) I/O流

3.区别与联系

           

          面向字符的流是专门用于字符数据的,面向字节的流通常用于一般目的的输入输出。从根本说,所有的数据都是由8位的字节组成,所以从逻辑上讲,所有的流可以被称为字节流。那么我们看看如何用字节流读取文本文件。

区别:

 字节流读取的时候,读到一个字节就返回一个字节,字符流使用了字节流读到一个或多个字节时先去查指定的编码表,将查到的字符返回。

字节流可以处理所有类型数据,如图片、mp3avi等,而字符流只能处理字符数据。

 字符流和字节流如何联系呢?答案——通过转换流!

          转换流是字节流和字符流之间的桥梁,该流对象中可以对读取到的字节数据进行啊制定编码表的编码转换。

          什么时候使用?

1)当字节和字符之间有转换动作时

2)流操作的数据需要进行编码表的指定时

具体对象表现:

1InputStreamReader:字节到字符的桥梁

2OutputStreamWriter:字符到字节的桥梁

 

      例子:使用InputStream类读取文本文件并显示

		import java.io.*;
		 class InputStream{
		   public static void main(String[] args){
		   try{
		       FileInputStream  s=new FileInputStream("D:/java/Hello.txt");
			   int c;
			   while((c = s.read())!= -1) System.out.write(c);
			   s.close();
			   }
			   catch(IOException iox){
			       System.out.println("Problem reading");
			   }
		   }
		}

                         运行结果:Java进击(二) I/O流


总结

     使用时首先,考虑最原始的数据格式是什么,数据来源是什么,其次考虑是输入还是输出,是否需要转换流,是否需要格式化,还要考虑是否要缓冲。

       数据来源:(1)是文件: FileInputStream, FileOutputStream, (字节流 )FileReader, FileWriter( 字符 );(2) byte[] : ByteArrayInputStream,ByteArrayOutputStream( 字节流 );(3) Char[]: CharArrayReader,CharArrayWriter( 字符流 );(4)是 String: StringBufferInputStream,StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 );(5 )网络数据流: InputStream, OutputStream,( 字节流 )Reader, Writer( 字符流 )

        数据格式:(1)二进制格式(只要不能确定是纯文本的) : InputStream,OutputStream 及其所有带 Stream 结束的子类 ;(2 )纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer及其所有带 Reader, Writer 的子类

       输入输出用:(1)输入: Reader, InputStream 类型的子类;(2 )输出: Writer, OutputStream 类型的子类

         要格式化的输出用:PrintStream, PrintWriter;

        要缓冲用:BufferedInputStream,BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )