您的位置:首页 > 编程语言 > Java开发

Java-IO流篇

2015-07-11 16:17 309 查看
1. java.io.File类

File类代表系统文件(文件和目录),磁盘上的文件和目录在Java程序中是用File类的实例来表示。

常用的构造方法:File (String pathname);File(File parent, String child) ;File(String parent,String child)

以pathname为路径创建File对象,如果pathname是相对路径,则是相对于Java的

系统属性user.dir中的路径(即当前字节码运行的目录)。

File类的一个常用属性:public static final String separator

存储了当前系统的路径分隔符。在Unix中该字段值为“/”,在Windows中为“\\”.

作用:实现了跨平台性,用这个表示分隔符就不用担心,不同系统的表示方式。

2.File类的常用方法

File的读写运属性:

boolean canExecute() ;//测试应用程序是否能够执行该File文件。

boolean canRead(); //是否可读取。

boolean canWrite(); //是否可以修改

判断:

boolean equals(Object obj); //测试此抽象路径名是否与给定对象相等

boolean exists(); //测试此文件或目录是否已存在

boolean isDirectory() ;//判断是否是一个目录

boolean isFile (); //判断是否是一个文件

boolean isHidden(); //判断是否是一个隐藏文件

获取:

long length(); //返回文件的长度,以字节为单位

long lastModified(); //返回文件最后一次被修改的时间

File getAbsoluteFile() ;//返回此的抽象路径名的绝对路径名形式。

String getAbsolutePath(); //返回此抽象路径名的绝对路径名字符串

String getName() ;//得到该文件名或该抽象路径的最后一个目录的名称。

String getParent();// 返回父目录的路径字符串,如果此路径没有指定父目录,则返回null

String getPath(); //将此抽象路径名转换为一个路径名字符串。

对文件的操作:

boolean createNewFile(); //当不存在时,创建一个新的空文件

boolean delete(); //删除此文件,如果是目录,必须是空才能删除,且删除的是最底的目录

boolean mkdir() ;//创建此抽象路径名指定的目录

boolean mkdirs(); //创建此目录,包括所有必需但不存在的父目录。

boolean renameTo( File dest);// 重新命名此文件

浏览目录中的文件和子目录

String [] list() ;//返回此目录的文件名和目录名的数组

File[] listFiles();//返回此目录中的文件和目录的File实例数组。

File[] listFiles(FilenameFilter filter) ;//返回此目录中满足指定过滤器的文件和目录

java.io.FilenameFilter接口:实现该接口的类实例可以用于过滤文件名。

3. File创建的步骤

1.文件或目录。

2.文件—a.先判断,f.exists(); b.创建 ,f.createNewFile(); //只能在已存在的路径下创建该文件。

目录—a.先判断,f.exists(); b.创建— f.mkdir();//路径上仅最后一个目录是不存在时

|— f.mkdirs();//路径上后面有多个目录不存在时

4.Java I/O 原理

数据流(Stream) 是指数据通信的通道。

Java程序对数据的输入,输出操作是以“流”的方式进行的。JDK中提供了各式的“流”类来获取不同种类的数据

5.流的分类

5.1 流的方向:

输入流:程序可以从中读取数据的流

输出流:程序可以向其中写入数据的流

5.1 数据传输单位

字节流:以字节为单位传输数据的流。

字符流:以字符为单位传输数据的流。

5.3 功能

节点流:用于直接操作目标设备的流

处理流:是对一个已存在的流的连接和封装,通过对数据的处理为程序提供更为强大,灵活的读写功能。

6.流的种类

所有的流类都位于java.io包中,都分别继承自以下四种抽象流类

输入流 ------ InputStream(字节流) ------ Reader(字符流)

输出流 ------ OutputStream(字节流) ------ Writer(字符流)

7.InputStream 抽象类

继承InputStream的流都是用于向程序中输入数据的,且数据的单位是一个字节。

InputStream |---- FileInputStream (节点流) |---- SequenceInputStream (处理流)

|---- PipedInputstream |---- ObjectInputStream

|---- StringBufferInputStream |---- FilterInputStream |---- DataInputStream

|---- ByteArrayInputStream |---- BufferdInputStream

7.1 InputStream 的基本方法(都有 throws IOException)

abstract int read() ;//从输入流中读取数据的下一个字节的整型表示(asii码值),遇到末尾是返回-1

int read(byte [] b) ;//从输入流中读取b.length个字节的数据存入b中,返回实际读取到的字节总数。

int read(byte [] b,int off,int len); //读取len个字节的数据,从off写入。

void close (); //关闭此输入流,并释放与此流相关联的所有系统资源

long skip(long n); // 跳过和丢弃此输入流中数据的n个字节,返回丢弃的字节数

int available (); //返回此输入流下一个方法可以(不受阻塞)读取(或跳过)的估计字节数,碰到末尾返回0

8.OutputStream 抽象类

继承OutputStream的流是程序用于向外输出数据的,且数据单位为一个字节

OutputStream |---- FileOutputStream (节点流) |---- ObjectOutputStream (处理流)

|---- PipedOutputStream |---- FilterOutputStream |---- DataOutputStream

|---- ByteArrayOutputStream |---- BufferedOutputStream

8.1 OutputStream 基本方法 (都有 throws IOException)

abstract void write (int b) ;//将指定的字节(对应asii码)写入此输出流

void write (byte []b) ;//将b.length个字节写入此输出流。

void write (byte []b,int off,int len) ;//从off开始,写入len个字节

void flush() ;//刷新此输出流并强制写出所有缓冲的输出字节。

void close(); //关闭此流,并释放相关资源

9. Reader 抽象类

继承Reader 的流都是向程序输入数据,数据单位为一个字符(16位)

Reader |---- PipedReader (节点流) |---- BufferedReader |---- LineNumberReader (处理流)

|---- StringReader(节点流) |---- FilterReader |---- PushbackReader (处理流)

|---- CharArrayReader(节点流) |---- InputStreamReader (处理流)|---- FileReader(节点流)

9.1 Reader 的基本方法

int read();//读取单个字符,以整型数值返回,达到末尾返回-1

int read( char[] c);// 读入char数组中,返回实际读取的字符数。

int read(char [] c,int off,int len);//读取len个字符,并从off开始写入

void close();//关闭流,并释放相关资源

long skip(long n);//跳过n个字符

10. Writer 抽象类

继承Writer的流是程序用于向外输出数据的,且数据单位为一个字符(16位)。

Writer |---- PipedWriter(节点流) |---- BufferedWriter (处理流)

|---- CharArrayWriter |---- PrintWriter (处理流)

|---- StringWriter |---- OutputStreamWriter(处理流) |---- FileWriter(节点流)

10.1 Writer 的基本方法

void writer (int c) ;//写入单个字符

void writer (char [] c);//写入字符数组

void writer (char [] c,int off, int len);//写入len个字符

void writer (String str);//写入字符串

void writer (String str,int off,int len);//写入字符串的某一部分

void flush();//强制将缓冲的数据写到目的地

void close();//关闭此流,但要先刷新它

11. 节点流类型



注意:

标准输入输出流

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

System.in的类型是InputStream.

System.out的类型是PrintStream是OutputStream的子类FilterOutputStream 的子类

12. 文件流

文件流主要用于操作文件

JDK提供了4种:

FileInputStream继承自InputStream

FileOutputStream继承自OutputStream

FileReader继承自Reader的InputStreamReader

FileWriter继承自Writer的OutputStreamWriter

13.转换流

在IO包中,有字节流和字符流,但是还存在转换流:字节流-字符流。

转换流用于字节流和字符流之间转换

JDK提供了两种转换流

InputStreamReader: 是Reader的子类,将输入的字节流变为字符流,即将一个字节流的

输入对象变成字符流的输入对象。

OutputStreamWriter:是Writer的子类,将输出的字符流变成字节流,即将一个字符流的

输出对象变为字节流的输出对象。



14. 内存流

内存流主要用于操作内存

ByteArrayInputStream 和 ByteArrayOutputStream

输入和输出可以从文件中来,也可以设置在内存之上。

ByteArrayInputStream主要完成将内容从内存读入程序之中,ByteArrayOutputStream

主要是将数据写入内存中。

  ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。

  ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。这就是数据目的地。

因为这两个流对象都操作的数组,并没有使用系统资源。所以,不用进行close关闭。

15.缓冲流

缓冲流是建立在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,还增加了一些新方法

JDK提供四种缓冲流:

BufferedInputStream 可以对任何的InputStream 流进行包装。

 BufferedOutputStream 可以对任何的OutputStream流进行包装。

BufferedReader 可以对任何的Reader流进行包装:新增了readLine()方法用于一次读取一行字符串('\r'或'\n'为一行结束)

BufferedWriter 可以对任何的Writer流进行包装:新增了newLine()方法涌入写入一个行分隔符。

注意: 对于缓冲输出流,最好在关闭此流前用flush() 方法将缓存区的数据刷新。

关闭处理流,会自动关闭所包装的所有底层流

16.数据流

DataInputStream ,DataOutputStream 属于处理流。提供了可以存取与机器无关的Java基本数据类型的方法

构造方法:参数为一字节型的节点流

DataInputStream (InputStream in);

DataOutputStream (OutputStream out);

17.打印流

PrintStream 和PrintWriter 都属于输出流,分别针对字节和字符。

两者:都提供了一系列重载的print和println方法输出各种类型的数据

两者:的输出操作不会抛出异常,System.out.就是PrintStream的一个实例

18.对象流

JDK提供的ObjectOutputStream和ObjectInputStream 类是用于存储和读取基本数据类型或对象的处理流

用ObjectOutputStream类保存基本数据类型或对象的机制叫序列化

用ObjectInputStream类读取基本数据类型或对象的机制叫反序列化

注意:能被序列化象所对应的类必须实现java.io.Serializable这个标识性接口

19.管道流(Piped)

PipedInputStream(PipedReader) ,PipedOutputStream(PipedWriter) 适合于线程之间的通信

使用管道流类,可以实现各个程序模块之间的松耦合通信,而不用对模块内部进行修改。达到“强内聚,弱耦合”的特点。

20.SequenceInputStream类

对一连串的输入流的读取操作

Vector<FileInputStream> v = new Vector<FileInputStream>();

v.add(new FileInputStream("c:\\1.txt"));
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));

Enumeration<FileInputStream> en = v.elements();

SequenceInputStream sis = new SequenceInputStream(en);

FileOutputStream fos = new FileOutputStream("c:\\4.txt");

byte[] buf = new byte[1024];

int len =0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}

fos.close();
sis.close();


21.RandomAccessFile 类

主要功能是完成随机读取功能,可以读取指定位置的内容

文件的打开模式:
◦“r” 以只读方式打开。调用结果对象的任何write 方法都将导致抛出IOException。
◦“rw” 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
◦“rws” 打开以便读取和写入,对于“rw”,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
◦"rwd" 打开以便读取和写入,对于"rw",还要求对文件内容的每个更新都同步写入到底层存储设备。

22.编码问题解决方法

法一:java.lang.string

//法一: xx编码-->new String(byte[]b,Charset xx)-->Stirng.getBytes(Charset yy)-->yy编码
public static void method_1() throws Exception
{
FileInputStream fis=new FileInputStream ("F:\\test\\test.txt");
File f=new File("F:\\test\\copy-test2.txt");
if(!f.exists())
f.createNewFile();
FileOutputStream fos=new FileOutputStream(f);

byte [] b=new byte[10];
int len=0;
while((len=fis.read(b))!=-1)
{
//思路:GB2312 到UTF-8,必须通过一个中间编码介质,这里是String
//将字节数组转换为string (其编码与操作系统一样是GBK)
//再将String转成其他编码的字节数组
String s=new String(b,0,len,"GB2312");
b=s.getBytes("UTF-8");
//fos.write(b,0,len);注意:这里是错误的,因为转码后的字节数组的长度变了,不是原来长度的字节数组
fos.write(b);
}
if(fos!=null)
fos.close();
if(fis!=null)
fis.close();
}


法二:java.io.InputStreamReader/OutputStreamWriter:桥转换

//法二(推荐):【IO流】xx编码-->inputstreamreader(file,"xx")--->outputStreamWriter(file,"yy")-->yy编码
public static void method_2()throws Exception
{
FileInputStream fis=new FileInputStream ("F:\\test\\test.txt");
File f=new File("F:\\test\\copy-test.txt");
if(!f.exists())
f.createNewFile();
FileOutputStream fos=new FileOutputStream(f);
//io流转接
InputStreamReader isr=new InputStreamReader(fis,"GB2312");
OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
//读取:
char [] cs=new char[1024];
int len=0;
while((len=isr.read(cs))!=-1)
{
osw.write(cs,0,len);
}
//关闭流
osw.flush();
osw.close();
isr.close();
}


方法三:java.nio.Charset

总结:

思路:1.明确源头,目的地是什么,内存,硬盘文件。

键盘(System.in属于inputstream),控制台(System.out.属于printstrem,outputstream)

2.流向,是输入,还是输出。

3.操作的数据类型,是字符还是字节

4.有哪些适合的包装流(处理流)适合题目要求,是缓冲流,数据流,内存流,转换流。

字节流的read()方法:为int类型

  字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。
  因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.
  那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。
  所以,为了避免这种情况将读到的字节进行int类型的提升。
  并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。而在写入数据时,只写该int类型数据的最低8位。

缓冲流读取方法是一行字符串,返回null表示文件的末尾

字节流读取int/byte,返回-1表示文件的末尾

  读取键盘录入:
  System.out:对应的是标准输出设备,控制台。
  System.in:对应的标准输入设备:键盘

Properties与IO流的结合使用

Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt");

//将流中的数据加载进集合。
prop.load(fis);

prop.setProperty("wangwu","39");

FileOutputStream fos = new FileOutputStream("info.txt");
//将prop中的信息写入fos中,并备注“haha”
prop.store(fos,"haha");

//	System.out.println(prop);
prop.list(System.out);

fos.close();
fis.close();


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: