IO(下)

来源:互联网 发布:知易商标网 编辑:程序博客网 时间:2024/06/05 15:00

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

IO:
    字节流:
        针对的字节数据,包括文本也包括媒体数据,如果是纯文本用字符流处理较为便捷。
        字节流所使用的缓冲区是一个byte[]。
    常用的对象:
        FileInputStream,FileOutputStream,BufferedInputStream,BufferedOutputStream。
    需求:
        copyMp3

 
        public void copyMp3()
        {
            FileInputStream fis = new FileInputStream("1.mp3");
            BufferedInputStream bufis = new BufferedInputStream(fis);
 
            FileOutputStream fos = new FileOutputStream("2.mp3");
            BufferedOutputStream bufos = new BufferedOutputStream(fos);
 
            int by = 0;
 
            while((by=bufis.read())!=-1)
            {
                bufos.write(by);
                bufos.flush();
            }
 
            bufos.close();
            bufis.close();
 
        }
 
    模拟BufferedInputStream。原理:其实将一个字节数组进行封装,通过方法将一批数据存入数组中,在通过数组的指针每一次返回数组中一个字节。当数组元素全部取出后,在存入一批新的数据,重复此过程。
 
    class MyBufferedInputStream
    {
        private InputStream in;
        private byte[] arr = new byte[1024*4];
        private int pos = 0,count = 0;
        MyBufferedInputStream(InputStream in)
        {
            this.in = in ;
        }
 
        public int myRead()throws IOException
        {
            if(count==0)
            {
                count = in.read(arr);
                if(count<0)
                    return -1;
                pos = 0;
                byte b = arr[pos];
                pos++;
                count--;
                return b;//return b&255;
            }
            else if(count>0)
            {
                byte b = arr[pos];
                pos++;
                count--;
                return b;//return b&0xff;
            }
            return -1;
        }
        public void myClose()throws IOException
        {
            in.close();
        }
    }
 
    当使用自定义的缓冲区时,居然出现的秒杀的情况,为什么会如此呢?
    因为mp3数据最终的二进制表现形式中,很容易出现连续N多1的情况,
    只要出现了连续的8个1,对于一个字节而言十进制体现形式就是-1。
    那么就满足while循环结束条件。程序终止。
    为了避免这种情况,在读到一个字节时,将该字节进行了提升变成int型。
    但是byte-1,变成int 还是-1。为了避免,在进行提升的过程中,保留的源字节的8为数据,并在前以补零方式进行提升。
 
    这样一个byte -1 变成了int 的255。这就避免了-1的情况。
    如何补的零呢?只要将读到的字节&255或者&0xFF.都可以。这也是read方法不是返回byte而返回int类型的原因。
 
    通过该过程就可以明确,read方法在对字节或者字符进行提升,而write方法在对提升后的int数据进行强转,
    只写出了最低的8位,或者最低的16位。
 
---------------------------------
 
字符流:
四个:
 
字节流:
四个。
 
为了实现字符和字节流之间的转换,出现了转换流。
 
转换流的由来,
当读到的字节数据都是纯文本的时候,而且文本中出现中文字符,那么在解析该字节数据时就需要指定编码表。
因为可以识别中的编码表不唯一。在使用转换流时,如果未指定编码表,那么默认使用本地码表。
 
InputStramReader:字节通向字符的桥梁
OutputStreamWriter:字符通向字节的桥梁
 
 
 
--------------------------------
 
流操作的基本规律:
1,明确数据源和数据目的。
    明确到底是使用输入流还是输出流。
2,明确要处理的数据是否是纯文本。
    明确到底是使用字符流还是字节流。
当明确体系后,到底该用该体系的哪个对象呢?
根据数据存在的设备而定,
数据源所在设备可以是,硬盘,键盘,内存。
数据目的所在设备可以是,硬盘,控制台,内存。
 
需求:
获取键盘录入,将录入信息存储到本地文件中。
 
    源:键盘录入,输入流。
    处理的数据:纯文本,字符输入流。Reader
    该用哪个对象呢?
    键盘录入System.in完成的。那么它是一个标准的字节输入流。InputStream。
 
    为了操作文本数据方便,将字节流转换成字符流。使用InputStreamReader。
    但是为了提高对字符操作的效率,BufferedReader.
 
    BufferedReader bufr = 
        new BufferedReader(new InputStreamReader(System.in));
 
    目的:本地文件(硬盘)输出流。
    处理的数据:纯文本,字符输出流。Writer。
    该用该体系的哪个对象呢?
        可以操作的文件FileWriter对象。
        为了提高写入流的效率。BufferedWriter.
 
 
    public void show()
    {
        BufferedReader bufr = 
            new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = 
            new BufferedWriter(new FileWriter("a.txt"));
 
        String line = null;
        while((line=bufr.readLine())!=null)
        {
            if("over".equals(line))
            break;
            bufw.write(line);
            bufw.newLine();
            bufw.flush();
        }
        bufw.close();
        bufr.close();
 
    }
    /*
    如果基本上面的分析,但不使用缓冲区,代码是一个什么样子呢?
    */
    public static void show()throws IOException
    {
        InputStreamReader isr = new InputStreamReader(System.in);
 
        FileWriter fw = new FileWriter("a.txt");
 
        char[] arr = new char[1024];
 
        int len = 0;
 
        while((len=isr.read(arr))!=-1)
        {
            System.out.println(len);
            String s = new String(arr,0,len-2);
            if("over".equals(s))
                break;
            fw.write(arr,0,len);
            fw.flush();
        }
        fw.close();
        isr.close();
    }
 
 
获取本地文本数据,将数据息存储到本地另一个文件中,按照UTF-8的编码形式。
 
源:硬盘,输入流。
数据:纯文本,字符输入流,Read。
该用哪个对象呢?
因为是文件FileReader为了提高效率BufferedReader.
 
目的:本地文件(硬盘)输出流。
    处理的数据:纯文本,字符输出流。Writer。
    该用该体系的哪个对象呢?
        可以操作的文件的对象,但是因为要将字符数据进行编码在进行存储,就需要使用字符向字节过滤的桥梁。OutputStreamWriter.
        就要使用转换流。而转换流要接收的对象都是字节流对象。所以要使用的可以操作的File的FileOutputStream。
        为了提高写入流的效率。BufferedWriter.
 
    public void show()
    {
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt));
 
        BufferedWriter bufw = 
            new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8"));
    }
 
 
-----------------------------
 
异常日志。
printStackTrace(PrintStream );
 
try
{
    int[] arr = new int[2];
    System.out.println(arr[3]);
}
catch(Exception e)
{
    Date d = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String time = sdf.format(d);
 
    try 
    {
        PrintStream out = new PrintStream("exception.log");
        e.printStackTrace(out);
 
        out.close();
    }
    catch(IOException e)
    {
        throw new RuntimeException("日志建立失败");
    }
 
}
 
 

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

0 0
原创粉丝点击