黑马程序员_JavaIO流(三)

字节流File读写操做

 字符流: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();
    }
}

  

 自定义字节流的缓冲区-read和write的特色

 

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

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

 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");
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

,,,,。。。。。。。。。。。。。。。。。。。。。。。。。

相关文章
相关标签/搜索