`
剑锋无刃
  • 浏览: 34052 次
  • 性别: Icon_minigender_1
  • 来自: 长沙市
最近访客 更多访客>>
社区版块
存档分类
最新评论

I/O流与文件

    博客分类:
  • java
阅读更多

 

I/O流

字节输入流:InputStream类为所有字节输入流的父类

三个基本的read()方法: 

       int read()

       从流里读出的一个字节。不推荐使用

       int read(byte[] b)

       将数据读入到字节数组中,并返回所读的字节数

       int read(byte[] b, int off, int len)

       off  从哪里开始读。

       len  读取多少。

       将输入流中最多 len 个数据字节读入字节数组。

其它方法: 

       void close() 

       关闭此输入流并释放与该流关联的所有系统资源。

       int available()

       返回不受阻塞地从此输入流读取的字节数。

       long skip(long n)

       跳过和放弃此输入流中的n个数据字节,该方法有可能失效。

       boolean markSupported()

       测试此输入流是否支持 mark 和 reset 方法。

       void mark(int n)

       在此输入流中标记当前的位置

       void reset()

       将此流重新定位到对此输入流最后调用 mark 方法时的位置。 

 

字节输出流:OutputStream类是所有字节输入流的父类

三个基本的write()方法: 

void write(int n)

将指定的字节写入此输出流。

void write(byte[] b) 

将 b.length 个字节从指定的字节数组写入此输出流。

void write(byte[] b, int off, int len)

将指定字节数组中从偏移量off开始的len个字节写入此输出流。

其它方法: 

void close()

       关闭此输出流并释放与此流有关的所有系统资源。

void flush()

       刷新此输出流并强制写出所有缓冲的输出字节。 

      

文件输入输出流:FileInputStream和FileOutputStream

要构造一个FileInputStream,所关联的文件必须存在而且是可读的。

如:

FileInputStream fis = new FileInputStream("myfile.dat"); 

要构造一个FileOutputStream,而输出文件已经存在,则它将被覆盖。  

如:

    FIleOutputStream fos = new FileOutputStream("results.dat"); 

    要想以追加的方式写,则需要一个额外的参数,如:

FileOutputStream outfile = new FileOutputStream("results.dat" ,true); //参数为true时输出为追加,为false时为覆盖。  

 

 

I/O流

流的概念:程序与数据来源之间的桥梁

流的分类:

按数据方向分:输入流和输出流

输入流:InputStream/Reader

OutputStream/Writer

按数据类型分:字节流和字符流

字节流:InputStream/OutputStream

字符流:Reader/Writer

按流的功能分:节点流和处理流

节点流用操作数据的来源。

处理流用来封装节点流,从而给节点流增加一个功能,不能独立存在,在关闭流时如果使用了处理流,只需关闭最外层的流就可以了。

区分节点流和处理流的小方法:

看构造器,节点流参数为数据来源,而处理流参数为其他流。

选择流的思路:

先考虑是输入流还是输出流,

再考虑是字节流还是字符流,

最后考虑是节点流还是处理流。

字符流:Reader和Writer所有字符流的父类型

Java技术使用Unicode来表示字符串和字符,而且提供16位版本的流,以便用类似的方法处理字符。 

如果构造了一个连接到流的Reader和Writer,转换规则会在使用缺省平台所定义的字节编码和Unicode之间切换。 

桥梁流:InputStreamReader和OutputStreamWriter(字节流转化成字符流的桥转换器)

这两个类不是用于直接输入输出的,他是将字节流转换成字符流的桥转换器,并可以指定编解码方式。

逐行读写流:BufferedReader/BufferedWriter

以上两个都是过滤流,需要用其他的节点流来作参数构造对象。

BufferedReader的方法:readLine():String ,当他的返回值是null时,就表示读取完毕了。要注意,再写入时要注意写换行符,否则会出现阻塞。

BufferedWriter的方法:newLine() ,这个方法会写出一个换行符。

管道流:线程交互的时候使用

PipedInputStream/PipedOutputStream

传送输出流可以连接到传送输入流,以创建通信管道。传送输出流是管道的发送端。通常,数据由某个线程写入 PipedOutputStream 对象,并由其他线程从连接的 PipedInputStream 读取。

注意:管道输出流和管道输入流需要对接。

数据流:DataInputStream和DataOutputStream

通过流来读写Java基本类,注意DataInputStream和DataOutputStream的方法是成对的。 

支持直接输出输入各种数据类型。

注意:使用DataOutputStream/DataInputStream时,要注意写入顺序和读取顺序相同,否则会将没有分割写入的信息分割不正确而读取出错误的数据。

Properties类:针对属性文件(*.properties,内容是name=value)进行操作,在java.util包下

load(InputStream inStream) 

          从输入流中读取属性列表(键和元素对)。

          getProperty(String key) 

          用指定的键在此属性列表中搜索属性。

java编码方式:

编码:把字符转换成数字存储到计算机中,按ASCII将字母映射为整数。

解码:把数字从计算机转换成相应的字符的过程。

不同的国家有不同的编码,当编码方式和解码方式不统一时,产生乱码。

因为美国最早发展软件,所以每种的编码都向上兼容ASCII 所以英文没有乱码。

ASCII(英文)                1个字符占一个字节(所有的编码集都兼容ASCII)

ISO8859-1(拉丁文)    1个字符占一个字节

GB-2312/GBK          1个字符占两个字节(多用于中文)

Unicode              1个字符占两个字节(网络传输速度慢)

UTF-8                变长字节,对于英文一个字节,对于汉字两个或三个字节。

中文编码时出现乱码的情况:

用流操作文件。

网页(动态静态)。

网络传递消息。

解决乱码的方式:

String temp = 乱码的字符串

temp = new String(temp.getBytes("ISO8859-1") , "GBK")   

将temp按照ISO8859-1的方式进行解码生成一个字节序列,然后在按照GBK的方式解码字节序列生成字符串。

File类:可表示文件或者目录

File下的方法是对磁盘上的文件进行磁盘操作,但是无法读写文件的内容。

 

构造器:

File(String pathname) //以文件的路径做参数

File类的方法:

boolean createNewFile() 

创建一个新文件

File createTempFile(String prefix, String suffix, File directory) 

            在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。会在前缀和后缀之间加一个随机数 

boolean mkdir()

创建一个新目录

boolean delete()

删除文件,删除的是创建File对象时指定与之关联创建的那个文件。

String[] List()

返回当前File对象下所有显文件和目录名(相对路径)

File[] ListFiles()

返回当前File对象(必须是目录)下的所有File对象,可以用getName()来访问到文件名。

boolean isDirectory()和boolean isFile()

判断究竟是目录还是文件。

boolean exists() 

判断文件或文件夹是否存在。

String getPath()

获得相对路径。

String getAbsolutePath()

获得文件的绝对路径

注意:

File类的对象实施表示一个文件并不是真正的文件,只是一个代理而已,通过这个代理来操作文件

创建一个文件对象和创建一个文件在java中是两个不同的概念。前者是在虚拟机中创建了一个文件,但却并没有将它真正地创建到OS的文件系统中,随着虚拟机的关闭,这个创建的对象也就消失了。而创建一个文件才是在系统中真正地建立一个文件。

例如:

File f=new File(“11.txt”); //创建一个名为11.txt的文件对象

f.CreateNewFile();     //真正地创建文件

 

RandomAccessFile: 

允许随机访问文件,类支持直接输出输入各种数据类型。

构造器:

RandomAccessFile(File file, String mode) 

          创建从中读取和向其中写入(可选)的随机存取文件流,该文件由 File 参数指定。 

RandomAccessFile(String name, String mode) 

          创建从中读取和向其中写入(可选)的随机存取文件流,该文件具有指定名称。 

mode( r:以只读方式打开      rw:可读可写,不存在则创建)

 

相关方法:

long getFilePointer()

返回文件指针的当前位置。 

void seek(long pos)

设置文件指针到给定的绝对位置。 

long length()

返回文件的长度。

对象流:ObjectInputStream和ObjectOutputStream(实现对象序列化)

对象流是过滤流,需要节点流作参数来构造对象,用于直接把对象写入文件和从文件中读取对象。

只有实现了Serializable接口的类型的对象才可以被读写,Serializable接口是个标记接口,其中没有定义方法。

对象会序列化成一个二进制代码,文件中保存对象的属性。

writeObject(o)、readObject()这两个是对象读写操作时用的方法。

Object o = new Object();

FileOutputStream fos=new FileOutputStream("Object.txt");

ObjectOutputStream oos=new ObjectOutputStream(fos);

oos.writeObject(o);

oos.close();

 

FileInputStream fis =new FileInputStream(“Object.txt”);

ObjectInputStream ois =new ObjectInputStream(fis);

Object o = (Object)Ois.readObject();

ois.close();

 

一个类中有其他类型的对象,那么,这个类实现了Serializable接口,在对象序列化时,也同样要求这个类中属性都能够对象序列化(基本类型除外)。

注意:

对于对象流的操作,在写对象时要一次写入完毕,如果使用追加模式写入,只会读取到上一次写入的对象,使用对象流写入时,会先写入一个头部,然后写入数据,最后加上结束符号,如果使用追加方式写入的话,那就会在结束符号继续向下写入,但是在读取时只会读到结束符为止,以后再次写入的数据就会丢失。

 

I/O流 对象流:ObjectInputStream和ObjectOutputStream 对象流是过滤流,需要节点流作参数来构造对象,用于直接把对象写入文件和从文件中读取对象。 只有实现了Serializable接口的类型的对象才可以被读写,Serializable接口是个标记接口,其中没有定义方法。 对象会序列化成一个二进制代码。 writeObject(o)、readObject()这两个是对象读写操作时用的方法。 Object o = new Object(); FileOutputStream fos=new FileOutputStream("Object.txt"); ObjectOutputStream oos=new ObjectOutputStream(fos); oos.writeObject(o); oos.close(); FileInputStream fis =new FileInputStream("Object.txt"); ObjectInputStream ois =new ObjectInputStream(fis); Object o = (Object)ois.readObject(); ois.close(); transient只能用来修饰属性。表示这个属性在对象序列化时将被忽略。 transient int num; 表示当我们进行序列化时忽略这个属性。 注意: 对于对象流的操作,在写对象时要一次写入完毕,如果使用追加模式写入,只会读取到上一次写入的对象。使用对象流写入时,会先写入一个头部,然后写入数据,最后加上结束符号,如果使用追加方式写入的话,那就会在结束符号继续向下写入,但是在读取时只会读到结束符为止,以后再次写入的数据就会丢失。 包名、类名和属性可以被序列化,方法和构造器不会被序列化的。 静态属性不会被序列化的。 属性会被递归序列化的,也就是一个类中有引用类型的属性,如果这个属性对应的类实现了Serializable接口,在对象序列化时,也同样会对这个类中的属性进行对象序列化,如果没有实现Serializable接口,则会抛出异常。 所有属性必须都是可序列化的,特别是当有些属性本身也是对象的时候,要尤其注意这一点。 网络中传递对象必须实现序列化。 nio无阻塞的I/O(优化的I/O) java.nio 定义块 Buffer类:一种用于特定的基本类型数据的容器 缓冲:就是块,用来存储内容。 容量:内存开辟的大小,根据类型的不同,有不同的空间。 界限:可用部分,即不应读取或写入的第一个元素的索引。 位置:当前指针的位置,从0开始。 容量>=界限>=位置 相关方法: int capacity() 返回此缓冲区的容量。 int limit() 返回此缓冲区的界限。 int position() 返回此缓冲区的位置。 Buffer flip() 相当于截断没有用的空间,然后把指针移向开头,使limit=position,position=0 Buffer position(int newPosition) 设置此缓冲区的位置。 当有大的文件需要处理的时候,为了不影响性能建议用直接缓冲。 Buffer有直接缓冲和间接缓冲两种。 只有ByteBuffer类提供了直接缓冲。使用直接缓冲,不影响程序。其它类想用直接缓冲需要进行转换。 java.nio.channels 对块进行读写的通道,类似于以前的流 Channel接口:用于 I/O 操作的连接 编程步骤: a. 先创建一个I/O流, b. 使用I/O流.getChannel()方法,获得通道, c. 创建大小合适的ByteBUffer, d. 通道的对象.read(buffer)/write(buffer)进行读写, e. 关闭所有的流和通道, f. 如果有多线程并发,可以使用"通道.lock()"获得FileLock对象,用FileLock.release() 释放此锁定。 g. 当遇到编码问题,使用CharSet、CharsetDecoder、CharsetEncoder三个类去解决 注意: 在读之前需要调用一下clear()方法,帮助读操作清理缓冲;写之前需要调用flip()方法,帮助写操作清理缓冲。 java.nio.charset 字符集,进行编码解码 Charset类:编码类,编码的信息 forName(String charsetName) 生成一个CharSet实例。 decode(ByteBuffer bb) 将此 charset 中的字节解码成 Unicode 字符的便捷方法。 encode(CharBuffer cb) 将此 charset 中的 Unicode 字符编码成字节的便捷方法。 CharsetDecoder类:解码器 能够把特定 charset 中的字节序列转换成 16 位 Unicode 字符序列的引擎。 CharsetEncoder类:编码器,编码的行为 能够把 16 位 Unicode 字符序列转换成特定 charset 中字节序列的引擎。

分享到:
评论

相关推荐

    Java课程设计报告书-学生版-1_I/O流与文件课程设计_

    本课程设计报告书——“Java课程设计报告书-学生版-1_I/O流与文件课程设计_”旨在帮助学生深入理解并掌握如何在Java中进行文件操作,通过实际的实验案例来学习文件对象和流类的应用。 一、Java I/O流概述 Java的I/O...

    关于I/O流读写文件

    I/O流读写文件 I/O流是Java编程语言中的一种基本概念,用于处理输入输出数据的功能。在Java中,I/O流是通过流的概念来实现的,流是一种抽象表示,用于表示输入设备或输出设备。根据不同的功能,I/O流可以分为输入流...

    实验七 C++的I/O流(验证性)

    C++的I/O流可以分为三种类型:标准流、文件流和字符串流。标准流是指输入和输出操作的最基本的形式,而文件流是指对文件的读写操作。字符串流则是指对字符串的输入和输出操作。 在实验中,我们使用了多种I/O函数,...

    C++ I/O流课件 很不错的哦

    C++中的I/O流是程序与外部世界交互的重要机制,主要涉及输入操作(读操作)和输出操作(写操作)。I/O流的概念来源于数据流,它就像一条河流,允许数据从一个源头流向另一个目的地。在C++中,数据流是以字节序列的...

    JAVA文件I/O流上传类

    JAVA文件I/O流上传类 MyFileSeparate 文件上传

    java基础之I/O流

    Java中的I/O流是程序与外部数据交互的重要机制,它允许数据在程序、文件、网络等之间流动。I/O流分为两大类:字符流(Character Stream)和字节流(Byte Stream),每类又分为输入流(Input Stream)和输出流...

    java对I/O流的处理

    Java中的I/O流处理是程序与外部设备交互数据的关键机制,包括从文件、网络、内存等数据源读取数据和向这些目标写入数据。I/O流系统在Java的`java.io`包中被实现,提供了丰富的类和接口来支持各种类型的流操作。 **I...

    怎么使用I/O编程???

    在Java编程中,I/O(Input/Output)处理是与外部世界交互的关键技术,涉及文件读写、网络通信等场景。I/O的核心思想是通过流(Stream)来传输数据,使得程序能从数据源读取数据或将数据写入目标。 **1.1 I/O简介** I...

    unix平台下I/O聚集和分离的一种方案

    在Unix操作系统环境中,I/O(Input/Output)操作是程序与外部设备交互的关键途径,包括读取数据、写入数据以及控制硬件设备等。在处理多个文件或套接字时,I/O聚集和分离是优化性能和管理资源的重要手段。本篇文章将...

    Java使用I/O流读取文件内容的方法详解

    Java使用I/O流读取文件内容的方法详解 Java使用I/O流读取文件内容的方法是Java编程中常用的文件读取方式。该方法可以将文件内容读取到程序中,并对其进行处理和分析。在Java中,I/O流是指数据流向某个对象的数据...

    Java I/O流通讯录

    在这个项目中,开发者通过I/O流实现了对文件的读写功能,从而构建了一个简单的通讯录系统。这个系统允许用户进行添加、删除、修改和查看联系人信息的操作,所有交互都在命令行或控制台界面进行,没有使用图形用户...

    Java 新I/O

    通道是数据传输的路径,连接到I/O设备(如文件、套接字或网络流)。通道可以是双向的,意味着数据可以从通道读取到缓冲区,也可以从缓冲区写入通道。常见的通道类型包括FileChannel、SocketChannel和...

    C#文件管理系统 I/O

    它主要依赖于C#中的输入/输出(I/O)功能,这些功能允许程序与磁盘上的文件进行交互。I/O操作在任何编程语言中都是至关重要的,尤其是在处理文件存储和检索的场景下。在C#中,.NET Framework提供了丰富的类库,如...

    java数据流 I/O系统

    总的来说,Java的I/O系统通过数据流模型提供了一种灵活且强大的方式来处理各种数据输入和输出需求,无论是简单的文件操作还是复杂的网络通信,都可以通过这套系统进行高效地处理。开发者可以根据需要选择适当的流...

    I/O流相关知识

    在Java编程语言中,输入/输出(I/O)流是一个至关重要的概念,它允许程序与外部...了解这些基本的I/O流概念和使用方法是Java程序员必备的技能,它们在处理文件、网络通信、标准输入输出等各种场景中都起着关键作用。

    Java I/O, 2nd Edition

    1. **Java I/O基础**:书中首先介绍了Java I/O的基本概念,如流、缓冲区、字符编码和文件操作。流是数据传输的核心机制,分为字节流和字符流两大类,包括输入流和输出流。缓冲区则可以提高I/O操作的效率,减少磁盘和...

    Java I/O 过滤流-带格式的读写操作

    过滤流(Filter Stream)是Java I/O框架中的一个重要概念,它提供了一种优雅的方式来进行数据的读写操作,同时允许我们添加额外的功能,如字符编码转换、数据压缩等。本篇文章将深入探讨Java I/O中的过滤流,以及...

    java i/o流读取写入字符流

    读取写入文件,javai/o流字符流 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee

Global site tag (gtag.js) - Google Analytics