Java-IO 输入输出流详解

一、文件的编码

              开发时一定要注意项目默认的编码!!!!!!!!

              文件操作的时候一定要记得关闭!!!!!!!!

       ASCII:美国标准信息交换码,用一个字节的7位可以表示一个字符

       ISO8859-1:拉丁码表,西欧标准字符集,用一个字节的8位表示

       GB2312:中文编码表,用两个字节来表示中文编码

       GBK:中文编码表的升级,融合了更多表示中文文字符号

       GB18030:GBK的取代版本

       BIG-5:同行与港台地区,是繁体字编码方案,俗称“大五码”

       Uicode:国际标准码,融合了多种文字

       UTF-8:是Unicode编码的实现方式,最多用三个字节来表示一个字符

    

       GBK编码     中文占用2个字节,英文占用1个字节

       UTF-8编码   中文占用3个字节,英文占用1个字节

       UTF-16be编码中文占用2个字节,英文占用2个字节

       Java是双字节编码 utf-16be,即java中每个字符占用两个字节

       

       当你想把一个字节序列变成一个字符串时,字节序列使用什么编码,就需要使用什么编码去显示的调用s.getBytes("字节序列的编码格式");,否则会出现乱码

       文本文件就是字节序列,可以是任意编码的字节序列,但是如果是在中文机器上直接创建文本文件,那么该文本文件只认识ANSI(本地编码)编码。如,新建一个TXT文件,内容为联通,打开则会出现乱码,是一种巧合,正好符合了UTF-8编码的规则

   

       Integer.toHexString(Byte);//以十六进制的方式显示

二、File工具类的使用

         1、File类用于表示文件和目录都可以

            File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问

         2、File类的基本API(看手册)

                构造函数的情况

                创建功能:createNewFile(),mkdir(),mkdirs()

                删除功能:delete()

                重命名功能:renameTo()

                判断功能:isFile(),isDirectory(),exists()等

                获取功能:getName(),getPath(),list()等

                文件过滤器的作用:list(FilenameFilter filter),返回满足指定条件的文件列表

                

            判断参数的时候,可以使用IllegalArgumentException参数抛出异常

            File.separator设置目录分隔符,Windows、Unix都识别

            相对目录是当前目录,也即在项目的根目录下

         3、遍历目录(递归 dir.listFiles())

            访问文件系统的时候因为是与JVM以外的资源进行交互,所以,写代码一定要严谨,把各种情况考虑到了

             

三、RandomAccessFile类的使用

       1、RandomAccessFile java提供的对文件内容的访问,既可以读,也可以写

          且支持随机访问文件,可以访问文件的任意位置

       2、Java文件模型

             在硬盘上的文件是byte byte byte存储的,是数据的集合

       3、打开文件 

1 RandomAccessFile raf =newRandomAccessFile(file,"rw");//rw,读写,r只读
2 //打开文件时,文件指针在开头,pointer = 0;
3 raf.write(byte);//write方法只会写一个字节,同时直接指针指向下一个位置
4 int b = raf.read();//每次读一个字节,java中每个字符占用两个字节,使用右移8位的方式分次写入
5 raf.seek(指针位置);//移动指针
6 raf.close();//文件读写完一定要关闭,否则可能会有意想不到的后果

在文件下载文件的时候,这种方式有很大的好处,每个线程下载文件的一部分,

          然后再拼接在一起,迅雷就是使用的这种方式,会记录指针的位置

四、字节流(InputStream、OutputStream,两个都是抽象类)

         1、I/O流用来处理设备之间的数据传输

            InputStream抽象了应用程序读取数据的方式

            OutputStream抽象了应用程序写出数据的方式

         2、EOF = End  读到 -1 就读到结尾

         3、输入流的基本方式主要是读

              int b = in.read();//读取一个字节无符号填充到int第八位,-1是EOF

              in.read(byte[] buf);//读入多个字节填充的字节数组

         4、输出流的基本方式主要是写

              out.write(int b);

              out.write(byte[] buf);

         5、FileInputStream具体实现了文件的读取操作

                while((b=in.read())!=-1){读一个文件}

                in.close();//一定要记得关闭流释放系统资源

                批量读取(速度非常快,效率高) vs. 单字节读取(不适合读大文件,效率很低)

          6、FileOutputStream具体实现了向文件中写数据的操作

                是删除文件重新创建,还是在原文件上追加内容,看构造方法

                自己实现文件的copy操作

                out.flush();

                out.close();

          7、数据输入输出流DataOutputStream/DataInputStream

                对流功能的扩展,是一个包装类,可以更加方便的读取int,long,字符等类型数据,本质是使用的一种装饰模式实现的

         8、字节缓冲流BufferedInputStream/BufferedOutputStream

                 为I/O提供了带缓冲区的操作,这种流模式提高了I/O的性能     

                 .write();

                 .flush();//刷新缓冲区,否则写入不到文件中

                 .close();

五、字符流(参考API)

       1、Java为什么引入字符流?

             操作文本时,尤其是包含中文字符等非ASCII码的字符会很不方便

             字符流 = 字节流+编码

             所以,要对编码问题非常清楚   

       2、java的文本(char)是16位无符号整数,是字符的Unicode编码(双字节)    

          文件是byte byte byte……的数据序列

          文本文件是文本序列按照某种编码方式序列化为byte的存储

       3、字符流(Reader Writer)操作的是文本文件

          一次处理一个字符,字符的底层仍然是基本的字节序列

          InputStreamReader 完成byte流按照编码解析为char流

          OutputStreamWriter 提供char流按照编码解析成byte流

       4、文件读写流  FileReader、FileWriter

             没法设置编码,必须回到字符流设置编码

       5、字符流的过滤器BufferedReader、BufferedWriter、PrintWriter

             readLine  可以一次读一行,一次写一行

             可以设置编码,不识别换行,单独写出换行操作

六、对象的序列化和反序列化

         1、将Object对象转换成byte序列,反之叫对象的反序列化

         2、序列化流(ObjectOutputStream),是过滤流---writeObject()

            反序列化流(ObjectInputStream),    ----readObject

         3、序列化接口(Serializable)

            对象必须实现序列化接口,才能进行序列化,否则将出现异常

            这个接口没有任何方法,只是一个标准,是标记接口

            

            对象序列化后,如果对再次对类文件修改,那么反序列化的时候就会出问题,那么怎么解决呢?

            需要在类中设置序列版本id,唯一标记,这样无论怎么修改读取的时候都不会再有问题   serialVersionUID

         4、transient关键字

               声明的元素不会进行JVM默认的序列化,也可以自己完成这个元素的序列化

               网络中传输时,并不是所有的元素都是有必要传输的,尤其是要考虑节约网络流量的时候

               在有些情况下,可以帮助我们提高性能(ArrayList在数组没有放满的时候,只把有效元素序列化)

         5、序列化中 子类和父类构造函数的调用问题

             父类实现了序列化接口,子类不需要再次实现,就能进行序列化    

             对子类对象进行反序列化操作时,如果其父类没有显示的实现序列化接口,那么其父类的构造函数会被调用

七、输入输出流的一些包装类

       1、打印流

               PrintStream  :字节打印流

               PrintWriter  :字符打印流

               集成了Print()格式化输出方法,可以操作任意类型的数据

       2、标准输入输出流

               System类的in、out字段

               默认输入设备是键盘,输出设备是显示器

               

               标准IO重定向

               System.setIn(InputStream);

               //重定向输出可以将打印到控制台的日志写到文件

               System.setOut(PrintStream);

               System.err(PrintStream);

       3、进程控制

              在Java内部执行其他操作系统的程序,并要求控制这些程序的输入输出时

              向OSExecute.command()传递一个command字符串   

Process process = new ProcessBuilder(command.split(" ")).start();

OSExecute.command("javap test");

//javap是java的一个反编译程序

八、IO操作过程中异常处理

        

       自己编程要用try-catch-finally包围起来,如果有异常尽量处理,千万不要仅仅是用printStackTrace()打印栈信息,在finally中进行流的关闭(判断引用不为空的话关闭),以确保一定能得到执行

时间: 2024-10-13 09:07:11

Java-IO 输入输出流详解的相关文章

Java实现文件写入——IO流(输入输出流详解)

输入输出的重要性:     输入和输出功能是Java对程序处理数据能力的提高,Java以流的形式处理数据.流是一组有序的数据序列,根据操作的类型,分为输入流和输出流. 程序从输入流读取数据,向输出流写入数据.Java是面向对象的程序语言,每一个数据流都是一个对象,它们提供了各种支持“读入”与“写入”操作的流类. Java的输入输出功能来自java.io 包中的InputStream类.OutputStream类.Reader类和Writer类以及继承它们的各种子类. (一)解析文件处理的奥秘 1

Java输入输出流详解

通过数据流.序列化和文件系统提供系统输入和输出. Java把这些不同来源和目标的数据都统一抽象为数据流.Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象. 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流. 1.1.Java流的分类 按流向分: 输入流: 程序可以从中读取数据的流.输出流: 程序能向其中写入数据的流. 按数据传输单

Java I/O输入输出流详解

一.文件的编码               开发时一定要注意项目默认的编码!!!!!!!!               文件操作的时候一定要记得关闭!!!!!!!!        ASCII:美国标准信息交换码,用一个字节的7位可以表示一个字符        ISO8859-1:拉丁码表,西欧标准字符集,用一个字节的8位表示        GB2312:中文编码表,用两个字节来表示中文编码        GBK:中文编码表的升级,融合了更多表示中文文字符号        GB18030:GBK的

转 Java输入输出流详解(非常详尽)

转  http://blog.csdn.net/zsw12013/article/details/6534619 通过数据流.序列化和文件系统提供系统输入和输出. Java把这些不同来源和目标的数据都统一抽象为数据流.Java语言的输入输出功能是十分强大而灵活的,美中不足的是看上去输入输出的代码并不是很简洁,因为你往往需要包装许多不同的对象. 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流. 1.1.J

java.IO输入输出流:过滤流:buffer流和data流

java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? 不带缓冲的操作,每读一个字节就要写入一个字节. 由于涉及磁盘的IO操作相比内存的操作要慢很多,所以不带缓冲的流效率很低. 带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里. 等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多! 这就是两者的区别

Java IO输入输出流 笔记

String s = "慕课ABC"; byte[] bytes1 = s.getBytes();//转换成字节序列用的是项目默认的编码 ,编码GBK for(byte b : bytes1) { //把字节(转换成)int以16进制的方式显示, 只显示后8位 System.out.println(Integer.toHexString(b & 0xff) + " "); } //gbk编码中文占用两个字节,英文占用1个字节 //utf-8编码中文占用3个字

Java IO输入/输出流的套接

缓冲字符流BufferedInputStream / BufferedOutputStream 文件操作流 InputStream / OutputStream java 输入输出流的套接,测试一下流链的速度 因为节点流在程序中并不是很常用,一般常通过过滤流将多个流套接在一起,利用各流的特性共同处理数据,套接的多个流构成了一个流链: 我们来分析他们的运行时间.(因为在不同的系统(maxOX,Linux,WIN(32/64))上运行的时间可能都不相同)我截取了几段时间来进行对比. 1.缓冲字符流B

JDK1.8 java.io.Serializable接口详解

java.io.Serializable接口是一个标志性接口,在接口内部没有定义任何属性与方法.只是用于标识此接口的实现类可以被序列化与反序列化.但是它的奥秘并非像它表现的这样简单.现在从以下几个问题入手来考虑. 希望对象的某些属性不参与序列化应该怎么处理? 对象序列化之后,如果类的属性发生了增减那么反序列化时会有什么影响呢? 如果父类没有实现java.io.Serializable接口,子类实现了此接口,那么父类中的属性能被序列化吗? serialVersionUID属性是做什么用的?必须申明

java Io 流类详解

关于java  流类的复习:习惯性的复习按照图结构一层层往下深入去了解去复习,最后通过代码来实现感觉印象会更深刻一些: 关于 I/O流:IO可以理解为JAVA用来传递数据的管道,创建一个IO,就相当于将管道与某个数据源连接到一起了. 字节流:数据流中最小的数据单元是字节.  字节:字节是一个八位的二进制数是一个很具体的存储空间: 字符流:数据流中最小的数据单元是字符:  字符:是一个抽象的符号,例如 1.2.3 .人  等   (并不是说直接传输字符,而是将字符按照指定的编码规则,转成对应的字节