字符流:java
FileReader FileWriter数组
BufferedReader BufferedWrtier网络
字节流:app
FileInputStream FileOutputStream工具
BufferedInputStream BufferedOutputStream优化
需求:想要操做图片数据,这时就要用到字节流。ui
import java.io.*; class FileStream { pubilc static void main(String[] args) { }
public static void readFile_3()throws IOException
{
FileInputStream fis = new FileInputStream("fos.txt");
//int num = fis.available();
byte[] buf = new byte[fis.available()];//定义一个刚恰好的缓冲区,不用再循环了。此方法要慎用。可能会发生内存溢出。
fis.read(buf);
//System.out.println("num"+num);
System.out.println(new String(buf));
fis.close();
} public static void readFile_2()throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); byte[] buf = new byte[1024];//建议定义1024的整数倍。 int len = 0; while((ch=len.read(buf))!=-1) { System.out println(new String(buf,0,len)); } fis.close(); } public static void readFile_1()throws IOException { FileInputStream fis = new FileInputStream("fos.txt"); int ch = 0; while((ch=fis.read())!=-1) { System.out println((char)ch); } fis.close(); } pubilc static void writerFile()throws IOException { FileOutputStream fos = new FileOutputStream("fos.txt"); fos.writer("abcde".getBytes()); fos.close();//不需刷新,但必须关闭资源。 } }
复制一个图片this
思路:编码
1,用字节读取流对象和图片关联。spa
2,用字节写入流对象建立一个图片文件,用于存储获取到的图片数据。
3,经过循环读写,完成数据的存储。
4,关闭资源。
import java.io.*; class CopyPic { pubilc static void mian(String[] args) { FileOutputStream fos = null; FileInputStream fps = null; try {
//写 fos = new FileOutputStream("c:\\2.bmp");
//读 fps = new FileInputStream("c:\\1.bmp"); byte[] buf = new byte[1024]; int len = 0; while((len=fis.read(buf))!=-1) { fos.write(buf,0,len); } }
catch(IOException e) { throws new RuntimeException("复制文件失败"); }
finally { try { if(fis!=null) fis.close(); } catch(IOException e) { throws new RuntimeException("读取关闭失败"); } try { if(fos!=null) fis.close(); } catch(IOException e) { throws new RuntimeException("写入关闭失败"); } } } }
演示MP3的复制,经过缓冲区。
import java.io.*; class CopyMp3 { public static void mian(String[] args)throws IOException { long start = System.currentTimeMillis(); Copy_1(); long end = System.currentTimeMillis(); System.out.println((end-start)+"毫秒"); } //经过字节流的缓冲区完成复制。 public static void Copy_1()throws IOException { BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\0.mp3")); BufferedOnputStream bufos = new BufferedOnputStream(new FileOnputStream("c:\\1.mp3")); int by = 0; while((by=bufis.read())!=-1) { bufos.write(by); } bufos.close(); bufis.close(); } }
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()throw IOException { //经过int对象读取硬盘上数据,并存储buf中。 if(count==0) { count = in.read(buf); if(count<0); return -1; byte b = buf[pos]; count--; pos++; return b&255; } else if(count>0) { byte b = buf[pos]; count--; pos++; return b&Oxff; } return -1; } public void myClose()throw IOException { in.close(); } }
注意:
read方法返回的是int类型,但仍是-1。是-1的缘由是由于在8个1面前补的是1所致使的。那么我只要在前面补0,既能够保留原字节数据不变,又能够避免-1的出现。
怎么补0呢?在返回数据时&上255/Oxff(255的十六进制表现形式)。
read的方法将数据进行提高(是为了不-1的发生),write方法将数据强制转换再返回(只写最低8位,有效数据)。
System.out:对应的是标准输出设备,控制台。
System.in:对应的是标准的输入设备:键盘。
import java.io.*; class ReadIn { public static void main(String[] args)throws IOException { InputStream in = System.in; int ch = in.read();//此方法是一个阻塞式方法。 System.out.println(ch);//被提高后,打印出来的是数字。 int ch = in.read(); System.out.println(ch);//回车符在编码边里面'\r'=13,'\n'=10 } }
需求:经过键盘录入数据。当录入一行数据后,就将该行数据进行打印,若是录入的数据是over,那么中止录入。
import java.io.*; class ReadIn { public static void main(String[] args)throws IOException { InputStream in = Ststem.in; StringBuilder sb = new StringBuilder(); while(true) { int ch = in.read(); if(ch=='\r') cuntinue; if(ch=='\n') { String s = sb.toString(); if("over".equals(s)) break; System.out.println(s.toUpperCase()); sb.delete(0,sb.length());//打印一次就要清空缓冲区一次。 } else { sb.append((char)ch); } } } }
经过刚才的键盘录入一行数据并打印其大写,发现其实就是都一行数据的原理,也就是readLine方法。能不能直接使用readLine方法开完成键盘录入的一行数据读取呢?
readLine方法是字符流BufferedReader类中的方法。而键盘录入的read方法是字节流InputStream的方法。
那么能不能将字节流转成字符流再使用字符流缓冲区的readLine方法呢?
import java.io.*; class TransStreamDemo { public static void main(String[] args)throws IOException { //获取键盘录入对象。 InputStream in = System.in; //将字节流对象转换成字符流对象,使用转换流,InputStreamReader InputStreamReader isr = new InputStreamReader(in); //为了提升效率,将字符串进行缓冲区技术高效操做,使用BuferedReader. BufferedReader bufr = new BufferedReader(isr); String line = null; while((line = bufr.readLine())!=null) { if("over".equals(line)) break; System.out.println(line.toUpperCase()); } bufr.close();//能够省略不写。最终都是System.in在操做。 } }
System.out返回的是PrintStream,是OutputStream的子类。
import java.io.*; class TransStreamDemo { public static void main(String[] args)throws IOException { InputStream in = System.in; InputStreamReader isr = new InputStreamReader(in); BufferedReader bufr = new BufferedReader(isr); OutputStream os = System.out; OutputStreamWriter osw = new OutputStreamWriter(os); BufferedWriter bufw = new BufferedWriter(osw); String line = null; while((line = bufr.readLine())!=null) { if("over".equals(line)) break; bufw.writer(line.toUpperCase()); bufw.newline(); bufw.flush(); //此方法不跨平台:osw.write(line.toUpperCase()+"'\r\n"); //osw.flush(); //System.out.println(line.toUpperCase()); } bufr.close();//能够省略不写。最终都是System.in在操做。 } }
代码进行优化后:
import java.io.*; class TransStreamDemo { public static void main(String[] args)throws IOException { //键盘录入的最多见写法。 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out)); String line = null; while((line = bufr.readLine())!=null) { if("over".equals(line)) break; bufw.writer(line.toUpperCase()); bufw.newline(); bufw.flush(); } } }
1,
源:键盘录入。
目的:控制台。
2,需求:想把键盘录入的数据存储到一个文件中。
源:键盘。
目的:文件。
3,需求:想要将一个文件的数据打印在控制台上。
源:文件。
目的:控制台。
源:
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
目的:
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
流操做的基本规律:最痛苦的是流对象有不少,不知道用哪个。
经过三个明确来完成。
1,明确源和目的。
源:输入流。InputStream Reader
目的:输出流。OutputStream Writer
2,操做的数据是不是纯文本。
是:字符流。
不是:字节流。
3,当体系明确后,再明确要使用哪一个具体的对象。
经过设备来进行区分:
源设备:内存,硬盘,键盘。
目的设备:内存,硬盘,控制台。
需求:
1,将一个文本文件中数据存储到另外一个文件中,复制文件。
源:由于是源,因此使用读取流。InputStream Reader
是否是操做文本文件?是。这是就能够选择Reader,这样体系就明确了。
接下来明确要使用该体系中的哪一个对象。
明确设备:硬盘,上的一个文件。
Reader体系中能够操做文件对象的是FileReader。
是否须要提升效率:是!加入Reader体系中缓冲区BufferedReader。
FileReader fr = new FielReader("a.txt");
BufferedReader bufr = new BufferedReader(fr);
目的:OutputStream Writer
是不是纯文本呢? 是。用Writer.
设备:硬盘。一个文件。
Writer体系中能够操做文件的对象是FileWriter。
是否须要提升效率:是!加入Writer体系中缓冲区BufferedWriter。
FileWriter fw = new FileWriter("b,txt");
BufferedWriter bufw = new BufferedWriter(fw);
练习:将一个图片文件中数据存储到另外一个文件中,复制文件。要按照以上格式本身完成三个明确。
2,需求:将键盘录入的数据保存到一个文件中。
这个需求中有源和目的都存在。那么分别分析。
源:InputStream Reader
是否是纯文本?是。Reader
设备:键盘。对应的对象是System.in。
不是选择Reader吗?System.in对应的不是字节流吗?
为了操做键盘的文本数据方便,转成字符流按照字符串操做是最方便的。
因此既然明确了Reader,那么就将System.in转换成Reader。
用了Reader体系中转换流,InputStreamReader
InputStreamReader isr = new InputStreamReader(System.in);
须要提升效率吗?须要。BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer
是不是纯文本?是!Writer
设备:硬盘。一个文件。使用FileWriter.
FileWriter fw = new FileWriter("c.txt");
须要提升效率吗?须要。
BufferedWriter bufw = new BufferedWriter(fw);
扩展一下,想要把录入的数据按照指定的编码表(utf-8),将数据存到文件中。
目的:OutputStream Writer
是不是纯文本?是!Writer
设备:硬盘。一个文件。使用FileWriter.(使用的是默认的编码表GBK)
可是存储时须要加入指定编码表UTF-8,而指定的编码表只有转换流能够指定。因此要使用的对象是OutputStreamWriter。
而该转换流对象要接收一个字节输出流,并且还能够操做文件的字节输出流。FileOutputStream。
OutputStreamWriter osw = new OutputStreamWriter(new FIleOutputStream("d.txt"),"UTF-8");
须要高效吗?须要。
BufferedWriter bufw = new BufferedWriter(osw);
因此,记住:转换流何时使用。字符和字节之间的桥梁,一般,涉及到字符编码转换时,须要用到转换流。
练习:将一个文本数据打印在控制台上,要按照以上格式本身完成三个明确。
System里提供两个静态方法来改变标准的的输入输出设备。
1,static void setIn(InputStream in):从新分配“标准”输入流。//System.in(new FileInputStream("PersonDemo.java");
2,static void setOut(PrintStream out):从新分配“标准”输出流。//System.out(new PrintStream("zz.txt");
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(Exceptiom 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("exception.log"); //ps.write(d.toString().getBytes()); ps.println(d.toString()); System.setOut(ps); } catch(IOException ex) { throw new RuntimeException("日志文件建立失败"); } e.printStackTrace(System.out);//将日志信息存到指定文件 } } }
LOG4G:网络工具包,专门用于创建Java的日志文件信息。
Properties类中的方法:
1,void list(PrintStream out):将属性列表输出到指定的输出流。
2,void list(PrintWriter out):将属性列表输出到指定的输出流。
import java.util.*; import java.io.*; class SystemInfo { public static void main(String[] args) { Properties prop = System.getProperties(); //System.out.println(prop); prop.list(new PrintStream("sysinfo.txt"); } }
,,,,。。。。。。。。。。。。。。。。。。。。。。。。。