JAVA 输入/输出流

来源:互联网 发布:汽车贷款月供怎么算法 编辑:程序博客网 时间:2024/05/02 01:15

JAVA 输入/输出流

本次分3个部分详细解说关于Java.io的使用

 

1、标准设备输入/输出

a) 标准输入/输出类System.

 

System类提供的静态方法中,分别以下几类功能:

标准输入、标准输出和错误输出流。

对外部定义的属性和环境变量的访问。

加载文件和库。

快速复制数组。

取得系统时间,即System.currentTimeMillis();

系统退出命令,即System.exit();

 

Read方法读取一个字节

package Test;

 

import java.io.IOException;

 

public class test {

public static void main(String[] args) {

int c;

try {

while ((c = System.in.read()) != 0) {// 读入一个字节

System.out.write(c);// 输出一个字节

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

运行该程序,在控制台输入一段字符后按回车键,就会调用read()函数的循环,每读到一个字节就会输出一个字节,因此回车前输入的字符串就会原样输出

 

Read(byte[] b) 读取一个字节数组

package Test;

 

import java.io.IOException;

 

public class test {

public static void main(String[] args) {

 

try {

byte[] b = new byte[100];// 创建字节数组

System.in.read(b);// 读取到数组中

System.out.write(b, 0, 100);// 输出字节数组

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

 

运行该程序,输入一个字符串,回车后就会输出回车前字符串的前100个字符。如果你输入的字符串长度小于100,那么补全100个字节,剩余的字节将会使用方框表示,实际上是这个字节没有数据。如果输入的字符串长度大于100,多余的字节就会补抛弃。

 

循环读取控制台的输入。

package Test;

 

import java.io.IOException;

 

public class test {

public static void main(String[] args) {

 

try {

while (true) {

byte[] b = new byte[100];// 创建字节数组

System.in.read(b);// 读取到数组中

String string = new String(b);

System.out.println(string);

// System.out.write(b, 0, 100);// 输出字节数组

}

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

 

 

 

 

 

控制台读写类Console.

2、文件基本处理

a) 文件操作类File

i. 文件操作类File:对目录或文件的创建、重命名、删除、文件列表、判断是否存在

 

File 类是Java文件处理的最基础的类,它用于实现对目录的创建、删除、对文件创建、

重命名、删除。因此。File类操作的对象分为两类:目录和文件

 

例子:

 

创建文件的四种方法:

public class FileTest {

public static void main(String[] args) {

File path = new File("D:/demo");// 目录对象

File file = new File("D:/demo/test.txt");// 文件对象

 

File file1 = new File("D:/demo","test.txt");// 目录文件一起创建

 

File file2 = new File("file://D:/demo/test.txt");// 创建一个新的File实例

 

File file3 = new File(path,"text.txt");

}

 

}

if(path.isDirectory()){//是否是目录

...

}

if(file.isFile()){//是否是文件

..FileTest.

}

 

if(path.exists()){ //检查目录是否存在

}

if(file.exists()){//检查文件是否存在

}

 

创建目录或文件:

Mkdir():创建一个目录

Mkdirs();创建所有目录

createNewFile();创建一个文件

 

创建多层目录的时候要用mkdirs(),mkdir()只能在已有目录下创建一个子目录,而对于createNewFi()则需要捕捉IOException。例如:

 if(!path.exists()){//如果目录不存在

path.mkdir();

path.mkdirs();

}

if(!file.exists()){//如果文件不存在则创建

try {

file.createNewFile();  

} catch (Exception e) {

// TODO: handle exception

}

查看目录下的文件列表,并输路径名:

File[] fileList = path.listFiles();

for(int i = 0 ;i<fileList.length;i++){ 

System.out.println(fileList[i].getAbsolutePath());

   生命名文件名:

//重命名

file.renameTo(new File("demp.txt"));

//删除目录

path.delete();

//删除文件

file.delete();

 

b)  文件搜索类FileFilterfilenameFilter

FileFilter使用实例(过滤txt文件)

package TestIO;

 

import java.io.File;

import java.io.FileFilter;

 

/**

 * 类说明

 *

 * @作者 liuwenliang

 *

 * @日期 2016-8-2

 *

 */

public class ExtensionFilterimplements FileFilter {

 

// 扩展名

private String extension;

 

public ExtensionFilter(String extension) {

this.extension = extension;

}

 

@Override

public boolean accept(File file) {

// 如果是目录则返回false

if (file.isDirectory()) {

return false;

}

// 取得文件名

String name = file.getName();

// 扩展名前的符号“.”

int index = name.lastIndexOf(".");

if (index == -1) { // 没有扩展名则返回false

return false;

} else if (index ==name.length() - 1) {//以点号结尾则返回false

return false;

} else {//如果扩展名相同,则返回true

return this.extension.equals(name.substring(index + 1));

}

}

 

}

 

package TestIO;

 

import java.io.File;

 

/**

 * 类说明

 *

 * @作者 liuwenliang

 *

 * @日期 2016-8-2

 *

 */

public class TestFile {

public static void main(String[] args) {

File file = new File("D:/demo");// 目录实例

ExtensionFilter txtFilter = new ExtensionFilter("txt");// 创建一个txt过滤器

File[] files = file.listFiles(txtFilter);// 使用过滤器查找txt文件

// 输出查找的文件列表

for (int i = 0; i < files.length; i++) {

System.out.println(files[i].getAbsolutePath());

}

 

}

 

FilenameFilter使用实现(过滤 .gif,.jpg,.png的文件)

package TestIO;

 

import java.io.File;

import java.io.FilenameFilter;

 

/**

 * 类说明

 *

 * @作者 liuwenliang

 *

 * @日期 2016-8-2

 *

 */

public class ImageFilter implements FilenameFilter {

/**

 *

 * 图片过滤

 *

 * @作者 liuwenliang

 *

 * @日期 2016-8-2

 *

 * @param filename

 * @return

 */

public boolean isGif(String filename){

if(filename.toLowerCase().endsWith(".gif")){

return true;

}else {

return false;

}

}

 /**

  *

  * jpg文件过滤

  *

  * @作者 liuwenliang

  *

  * @日期 2016-8-2

  *

  * @param filename

  * @return

  */

public boolean isJpg(String filename){

if(filename.toLowerCase().endsWith(".jpg")){

return true;

}else{

return false;

}

}

/**

 * Png文件过滤

 * 方法说明

 *

 * @作者 liuwenliang

 *

 * @日期 2016-8-2

 *

 * @param filename

 * @return

 */

public boolean isPng(String filename){

if(filename.toLowerCase().endsWith(".png")){

return true;

}else {

return false;

}

}

//在该类的accept()函数中,可以直接通过文件名filename进行过滤,这里分别调用了3种类弄的过滤

//子函数。同样地,我们在测试类TestFile中添加如下的代码进行测试。

@Override

public boolean accept(File dir, String name) {

// TODO Auto-generated method stub

return (isGif(name) || isJpg(name)||isPng(name));

}

 

}

 

package TestIO;

 

import java.io.File;

 

/**

 * 类说明

 *

 * @作者 liuwenliang

 *

 * @日期 2016-8-2

 *

 */

public class TestFile {

public static void main(String[] args) {

File file = new File("D:/demo");// 目录实例

ImageFilter imageFilter = new ImageFilter();//创建一个图片过滤器

File[] images = file.listFiles(imageFilter);

for (int i = 0; i < images.length; i++) {

System.out.println(images[i].getAbsolutePath());

}

}

}

通常建议使用FilenameFilter类进行文件过滤

c) 文件随机读写类RandomAccessFile.

 

刚才讲解的File类,以及FileFilterFilenameFilter类,都是对文件和目录进行操作,不能名实现对文件内容的读写。要实现对文件内容的随机读写,可以使用RandomAccessFile类。

 

下面将通过RandomAccessFile操作打开关闭文件、读取文件和写入文件3个方面讲解RandomAccessFiler的使用

    

1) 打开与关闭文件

 

创建随机访问文件的实例,可以使用下面的两构造函数

RandomAccessFile(File file,String mode)

RandomAccessFile(String file,String mode)

 

第一种是通过一个File对象创建,第二种则直接指向文件名。其中的参数mode表示对目标文件的访问模式;

访问模式有四种:

r” 以只读方式打开。

“rw”打开以便读取和写入,如果该文件尚不存在,则尝试创建该文件

“rws”打开以便读取和写入,对于“rw”,还要求对文件的内容或元素的每个更新都同步写入底层存储设备

“rwd”打开以便读取和写入,对于”rw”,还要求对文件内容的每个更新都同步写入到底层存储设备

//采用读写模式打开文件:D:/demo/test.txt

RandomAccessFile file = new RandomAccessFile("D:/demo/test.txt",

"rw"); 

//关闭文件

file.close(); 

打开文件后必须关闭,否则该文件会被占用。

 

2) 读取文件

//读取文件长度

long size = file.length();

//设置文件指针位置

file.seek(4);

//读取一个数据字节:read()

int c = file.read();

//读取字节数组:read(byte[] b)

byte[] b = new byte[3];//创建字节数组

file.read(b);//读取到字节数组

String str = new String(b);//转化为字符串

System.out.println(str);//输出字符串

//灵活读取字节数组:read(byte[] b, int off,int len)

//len必须不能大于从off开始所剩余的数组的长度,否则会出现数组越界的异常IndexOutOfBoundsException;

byte[] b2 = new byte[3];//创建字节数组

file.read(b2,1,2);//读取到字节数组

String str2 = new String(b);//转化为字符串

System.out.println(str2);//输出字符串

//读取固定类型的数值

file.readBoolean();

file.readByte();

file.readChar();

file.readDouble();

file.readFloat();

file.readInt();

file.readLong();

file.readShort();

file.readUnsignedByte();

file.readUnsignedShort();

//读取一行字符串:readLine();

System.out.println(file.readLine());

//读取中文字符:readUTF()

System.out.println(file.readUTF());

 

3) 写入文件

// 写入一个数据字节:write()

file.write(100);

//写入字节数组:write(byte [] b)

byte[] bw = new byte[3];//创建字节数组

bw[0] = 100;//写入字符d的ASCII码

bw[1] = 101;//写入字符e的ASCII码

bw[2] = 102;//写入字符f的ASCII码

file.write(bw);//写入字节数组

//执行后,就会在指针位置写入“def”3个字符。

//灵活写入字节数组:read(byte[] b ,int off,int len)

file.write(bw,1,2);

//写入一个字符串:writeBytes() 与 writeChars()

file.writeBytes("AA");

file.writeChars("DD");

//写入中文字符:writeUTF()

file.writeUTF("中国");

 

 

3、输入/输出流

a) 流的动作原理:包括输入流、输出流、输入流链、输出流链的运作原理

 

Java IO最关键的4个父类是:InputStream(输入字节流)OutputStream(输入字节流)、Reader(输入字符流)、Writer(输出字符流).它们都是public abstract class类。

InputStream和OutputStream对于数据的传送是以字节“byte”为单位的,而ReaderWriter对于数据的传送是以字符“character”为单位的。所以我们看到java.io包中的类大体上可以分为两大类,一类是以byte处理为主的Stream类,它们都是愉XXXStream方式命名的;一类是以character处理为主的Reader/Writer类,它们都是以XXXReaderXXXWriter的方式命名的。


流的运作原理:

 

1、输入流

如果一个程序可以用FileImputStream类从一个磁盘文件读取数据,这就是输入流

 

FileInputStream这样的处理器叫做流处理器,它就像流的管道一样,从一个流源吸入某种类型的数据,并输出某种类型的数据

 

 

2、输出流

同样道理,也可以用输出FileOutputStream类向一个磁盘文件写数据

 

在实际应用中,程序需要写出的通常是非常结构化的信息,因此这些byte类型的数据实际上是一些数值、文字、源代码等。

 

3、输入流链

 

JavaI/O库提供了一个称做链接(Chaining)的机制,可以将一个流处理器跟另一个处理器首尾相撞,以其中之一的输出作为另一个的输入,形成一个流管道的链接。

例如:DataInputStream流处理器可以把FileInputStream流对象的输出当做输入,将byte类型的数据转换成Java的原始类型和String类型的数据。

   

 

4、输出流链

 向一个文件写入byte类型的数据不是一个简单的过程。一个程序需要向一个文件里写入的数据往往都是结构化的,而byte类型则是原始类型。因此在写的时候必须经过转换。

DataOutputStream流处理器提供了接收原始数据类型和String数据类型,而这个流处理器的输出数据则是byte类型。也就是说DataOutputStream可以将源数据转换成Byte类型的数据,再输出。

这样一来,就可以将DataOutputStreamFileOutputStream链接起来,这样程序就可以将原始数据类型和String类型的源数据写入这个链接好的双重管道里面,达到将结构化数据写到磁盘文件里面的目的

 

 

流处理器所处理的流必定都有流的输入源,而如果将流类所处理的流源分类的话,基本可以分成两大类。

 

一类:数组、StringFile等,这一种叫原始流源

二类:同样类型的流用做链接流类的流源,叫链接流源。

 

 

b) 输入字节流InputStream:11个实现类,包括如下:

 

 

InputStream 的作用是标志那些从不同输入源产生输入的类。InputStream是所有输入字节流的抽象父类,因此不能够直接构造InputStream的实例,必须通过它的子类来进行构造。由于它是抽象类因此提供了一些抽象接口和固有的函数实现

 

 

 

Java.io 的包中为我们提供了inputStream的实现类:

 

 

根据输入源的不同,共分为如下几种类型。

ByteArrayInputStream:把内存中的一个缓存区作为InputStream使用。

 

凡是涉及输入流,输出流操作的,都需要进行异常捕捉

FileInputStream:把一个文件作为FileInputStream,实现对文件的读取操作。

FileInputStream从文件系统中的某个文件中获得输入字节,适用于读取诸如图像数据之类的原始字节流。

 


 

ObjectOutputStream:实现对对象的读取操作  StringBufferInputStream:把一个String对象作为InputStream.

 并且它还有3个特殊的实现:

PipedInputStream:实现了管道(pipe)概念,主要在线程中使用。

SequenceInputStream:把多个InputStream合并为一个InputStream.

FilterInputStream:输入对流进行各种过滤操作。FileterInputStream还有一组过滤器的具体实现。

BufferedInputStream:缓存过滤器

DataInputStream:数据过滤器

LineNumberInputStream:行号过滤器

PushbackInputStream:回退过滤器

inputStream的实现,它们的功能各有不同,因此选用它们的时机也各不相同。可分为3

1、根据输入源的不同选用的类

a) 数组:ByteArrayInputStream.

b) 文件:FileInputStream.

c) 对象:ObjectInputStream.

d) 字符串:StringBufferInputStream.

2、要把流的串联选择的类

a) 管道:PipeInputStream

b) 序列:SequenceInputStream

3、对流时行过滤选择的类

a) 过滤:FilterInputStream.

b) 缓存:BufferedInputStream.

c) 数据:DataInputStream

d) 行号:LineNumberInputStream

e) 推回:PushbackInputStream.

其中的输入源类是我们在输入源对象时的第一个类,只需要根据我们要输入的数据类型选择即可。通常使用较广泛的是文件FileInputStream和字符串StringBufferInputStream.过滤器类在我们需要对输入流增加各种功能时的选择,比如需要提高效率时可以使用BufferedInputStream,根据行时行检索时可以使用LineNumberInputStream,读取简单数据类型时可以使用DataInputStream,读取对象数据类型时可以使用ObjectInputStream.

根据实际应用的需要,使用最多的是FileInputStreamBufferedInputStream的结合,即在读取文件时使用缓存读取,这样可以提高读取文件的效率。StringBufferInputStream也是一种比较常用的类,通常可能需要我们根据某一个字符串来创建一个输入流。

 

c) 输出字节流OutputStream:8个实现类,包括如下

 

OutputStream的一系列实现,图:

 

 

ByteArrayOutputStream;把信息存入内存中的一个缓存区中

FileOutputStream;把信息存入文件中

ObjectOutputStream;把一个对象作为OutputStream,实现对对象的写入操作。

PipedOutputStream;实现pipe的概念,主要在线程中使用

FilterOutputStream;对输出流时行各种过滤操作

BufferedOutputStream;缓存过滤器

DataOutputStream;数据过滤器

PrintStream;格式化过滤器

根据它们的功能,可以分为3

1、根据输出源的不同选用的类

a) 数组:ByteArrayOutputStream.

b) 文件:FileOutputStream.

c) 对象:ObjectOutputStream

2、根据流的串联选择的类

a) 管理:PipeOutputStream

3、对流进行过滤选择的类

a) 过滤:FilterOutputStream

b) 缓存:BufferedOutputStream.

c) 数据:DataOutputStream

d) 格式化:PrintStream.

根据实际应用的需要,使用最多的是FileOutputStreamBufferedOutputStream的结合,即在写入文件时使用缓存,这样可以提高写入文件的效率

 

d) 输出字符流Reader:共8个实现类,包括扣下:

 

Reader实现类的结构图:

 

根据输入源的不同,共包括如下几种类型:

CharArrayReader:与ByteArrayInputStream对应,用于读入内存中的字符数组。

FileReader:与FileInputStream对应,用于读取文件内容

StringReader:与StringBufferInputStream对应,用于读取字符串。

PipedReader:与PipedInputStream对应

FilterReader:与FilterReader对应

BufferedReader:与BufferedInputStream对应

LineNumberReader:与LineNumberInputStream对应,行号读取类。

PushbackReader:与PushbackInputStream对应,推回过滤器。

根据实际应用的需要,使用最多的是FileReaderBufferedReader的结合,即在读取文件时使用缓存读取,这样可以提高读取文件的效率。

 

e) 输出字符流Writer: 7个实现类,包括如下:

 

Writer的一系列实现图

 

 

CharArrayWriter:与ByteArrayOutputStream对应,用于写入内存中的字符数组。

FileWriter:与FileOutputStream对应,用于写入文件内容。

StringWriter:无与之对应的以字节为导向的stream,用于写入内存中的字符串。

PipedWriter:与pipedOutputStream对应

FilterWriter:与FilterOutputStream对应

BufferedWriter:与BufferedOutputStream对应

PrintWriter:格式化过滤器

根据实际应用的需要,使用最多的是FileWriterBufferedWriter的结合,即在写入文件时使用缓存,这样可以提高写入文件的效率。

0 0
原创粉丝点击