Java IO文件流

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java IO文件流相关的知识,希望对你有一定的参考价值。


package com.zb.io.test;


import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

import java.io.Reader;

import java.io.Writer;


public class IO {

public static final String PATH1 = "temp/1.txt";

public static final String PATH2 = "temp/2.txt";

public static final String PATH3 = "temp/3.txt";

public static final String PATH4 = "temp/4.txt";

public static final String PATH5 = "temp/5.txt";

 

public static void main(String[] args) {

try {

// 创建文件夹和文件

File file = createDirAndFile(PATH1);

// 使用字节流OutPutStream写入文件信息

setFileByByteIoOutPutStream(file);

// 使用字节流InPutStream读取文件信息

getFileByByteIoInPutStream(file);

file = createDirAndFile(PATH2);

//使用Writer写入文件信息

setFileByCharIoWriter(file);

//使用Reader读取文件信息

getFileByCharIoReader(file);

file = createDirAndFile(PATH3);

//使用OutputStreamWriter写入文件信息

setFileByCharIoOutputStreamWriter(file);

//使用InputStreamReader读取文件信息

getFileByCharIoInputStreamReader(file);

file = createDirAndFile(PATH4);

//使用BufferedWriter写入文件信息

setFileByCharIoBufferedWriter(file);

//使用BufferedReader读取文件信息

getFileByCharIoBufferedReader(file);

file = createDirAndFile(PATH5);

//使用BufferedOutputStream写入文件信息

setFileByBufferedOutputStream(file);

//使用BufferedInputStream读取文件信息

getFileByBufferedInputStream(file);

 

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 在指定的目录创建文件夹和文件

* @param path 

* @throws IOException

*/

public static File createDirAndFile(String path) throws IOException {

File fileDir = new File("temp");

if (!fileDir.exists() && !fileDir.isDirectory()) {

System.out.println("开始创建新的文件夹!");

fileDir.mkdir();

} else {

System.out.println("文件夹已存在,无需创建!");

}

System.out.println("当前文件夹的路径是:" + fileDir.getAbsolutePath());

File file = new File(path);

if (!file.exists()) {

System.out.println("开始创建新的文件!");

file.createNewFile();

} else {

System.out.println("文件已存在,无需创建!");

}

System.out.println("当前文件的路径是:" + file.getAbsolutePath());

return file;

}


/**

* 使用OutPutStream写入文件

* @throws IOException

*/

public static void setFileByByteIoOutPutStream(File file) throws IOException {

StringBuffer sb = new StringBuffer("使用字节流OutPutStream写入文件信息!");

sb.append("\r\n在java中,可以使用InputStream对文件进行读取,就是字节流的输入。!");

sb.append("\r\n当读取文件内容进程序时,需要使用一个byte数组来进行存储,如此会有如下两个问题:");

sb.append("\r\n1.如何建立合适大小的byte数组,如果已知输入流的大小。");

sb.append("\r\n2.如果不知输入流的大小,则肯定需要建立一个很大的byte数组,那么byte中很可能有空的内容,那么如何正确合适的将byte数组的中的内容输出?");

sb.append("\r\n先看第一个问题:解决之道就是获取输入流的大小,创建此大小的byte数组。代码如下:view plaincopy to clipboardprint?\r\n//使用InputStream从文件中读取数据,在已知文件大小的情况下,建立合适的存储字节数组   ");

sb.append("\r\n第二个问题:问题的解决之道就是获得输入流何时结束,它在byte中的尾索引位置。可以通过read()方法实现,read()返回读取的字节内容,当内容为空时返回-1。利用此特征可以解决第二个问题。");

OutputStream out = new FileOutputStream(file);

out.write(sb.toString().getBytes());

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

out.flush();

out.close();

System.out.println("字节流写入文件完成!!!");

}


/**

* 使用InputStream读取文件

* @throws IOException

*/

public static void getFileByByteIoInPutStream(File file) throws IOException {

InputStream in = new FileInputStream(file);

System.out.println("===============字节流开始读取文件===================");

//创建合适文件大小的数组

byte b[]=new byte[(int)file.length()];     

//读取文件中的内容到b[]数组

 in.read(b);

 //关闭流

 in.close();

 System.out.println(new String(b));

in.close();

System.out.println("\n===============文件流读取完成===================");

}

/**

* 使用Writer写入文件

* @param file

* @throws IOException 

*/

private static void setFileByCharIoWriter(File file) throws IOException {

Writer wr = new FileWriter(file);

StringBuffer sb = new StringBuffer("使用字符流Writer写入文件信息!");

sb.append("\r\n java中的字符是Unicode编码的, InputStream和OutputStream都是用来处理字节的,在处理字符时需要用getBytes()转换成字节,这就需要编写字节、字符之间的转换代码java中提供了单独的类对IO设备进行字符输入与输出!");

sb.append("\r\n Reader和Writer是所有字符流类的的抽象基类,用于简化对字符串的输入输出编程,即用于读写文本数据");

sb.append("\r\n 二进制文件和文本文件的区别。");

sb.append("\r\n 如果一个文件专用于存储文本字符,而又没有包含文本之外的字符,就可称之为文本文件。除此之外的文件就是二进制文件");

sb.append("\r\n Reader和Writer两个类主要用于操作文本数据的内容,而InputStream和OutputStream主要操作二进制格式的内容  ");

sb.append("\r\n 使用FileWriter写入字符数据比FileOutputStream要简便很多,但是FileReader并不比FileInputStream读取字符数据要简便多少,都是要先读取到一个字符数组或者字节数组中,然后把数组转换成字符串。");

wr.write(sb.toString());

wr.flush();

wr.close();

System.out.println("字符流写入文件完成!!!");

}

/**

* 使用Reader读取文件

* @throws IOException 

*/

public static void getFileByCharIoReader(File file) throws IOException{

Reader reader = new FileReader(file);

char[] buffer = new char[1024];

int length = reader.read(buffer);

System.out.println("===============字符流开始读取文件===================");

String text = new String(buffer,0,length);

System.out.println(text);

reader.close();

System.out.println("\n===============文件流读取完成===================");

}

/**

* 使用OutputStreamWriter写入文件

* @param file

* @throws IOException 

*/

private static void setFileByCharIoOutputStreamWriter(File file) throws IOException {

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file));

StringBuffer sb = new StringBuffer("使用OutputStreamWriter写入文件信息!");

sb.append("\r\n 读取文件流时,经常会遇到乱码的现象,造成乱码的原因当然不可能是一个,这里主要介绍因为文件编码格式而导致的乱码的问题。首先,明确一点,文本文件与二进制文件的概念与差异。");

sb.append("\r\n 文本文件是基于字符编码的文件,常见的编码有ASCII编码,UNICODE编码、ANSI编码等等。二进制文件是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思(这样一个过程,可以看作是自定义编码。)");

sb.append("\r\n 因此可以看出文本文件基本上是定长编码的(也有非定长的编码如UTF-8)。而二进制文件可看成是变长编码的,因为是值编码嘛,多少个比特代表一个值,完全由你决定。");

sb.append("\r\n 对于二进制文件,是千万不能使用字符串的,因为字符串默认初始化时会使用系统默认编码,然而,二进制文件因为自定义编码自然与固定格式的编码会有所冲突,所以对于二进制的文件只能采用字节流读取、操作、写入。");

sb.append("\r\n  对于文本文件,因为编码固定,所以只要在读取文件之前,采用文件自身的编码格式解析文件,然后获取字节,再然后,通过指定格式初始化字符串,那么得到的文本是不会乱码的。  ");

sb.append("\r\n  虽然,二进制文件也可以获取到它的文本编码格式,但是那是不准确的,所以不能同日而语。");

out.write(sb.toString());

out.flush();

out.close();

}

/**

* 使用InputStreamReader读取文件

* @param file

* @throws IOException 

*/

private static void getFileByCharIoInputStreamReader(File file) throws IOException {

InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"UTF-8");

int length = -1;

char[] buffer = new char[1024];

StringBuffer sb = new StringBuffer(0);

System.out.println("===============InputStreamReader开始读取文件===================");

while((length=isr.read(buffer,0,1024))!=-1){

sb.append(buffer,0,length);

}

isr.close();

System.out.println(sb.toString());

System.out.println("===============InputStreamReader读取完成===================");

}

/**

* 使用BufferedWriter写入文件

* @param file

* @throws IOException 

*/

private static void setFileByCharIoBufferedWriter(File file) throws IOException {

BufferedWriter bw = new BufferedWriter(new FileWriter(file));

StringBuffer sb = new StringBuffer("使用BufferedWriter写入文件信息!");

sb.append("\r\n java.io.BufferedReader和java.io.BufferedWriter类各拥有8192字符的缓冲区。");

sb.append("\r\n 当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。");

sb.append("\r\n 如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。 ");

sb.append("\r\n 如果缓冲区中的数据满了,才会一次对目的地进行写出。");

sb.append("\r\n  从标准输入流System.in中直接读取使用者输入时,使用者每输入一个字符,System.in就读取一个字符。为了能一次读取一行使用者的输入,使用了BufferedReader来对使用者输入的字符进行缓冲。  ");

sb.append("\r\n  readLine()方法会在读取到使用者的换行字符时,再一次将整行字符串传入。");

bw.write(sb.toString());

//BufferedWriter换行的方法

bw.newLine();

bw.flush();

bw.close();

}

/**

* 使用BufferedReader读取文件

* @param file

* @throws IOException 

*/

private static void getFileByCharIoBufferedReader(File file) throws IOException {

BufferedReader br = new BufferedReader(new FileReader(file));

System.out.println("===============BufferedReader开始读取文件===================");

int length = -1;

String text = br.readLine();

while((text=br.readLine())!=null){

System.out.println(text);

}

System.out.println("===============BufferedReader读取文件完成===================");

}

/**

*使用BufferedOutputStream写入文件

* @throws IOException 

*/

private static void setFileByBufferedOutputStream(File file) throws IOException {

BufferedOutputStream bos = new  BufferedOutputStream(new FileOutputStream(file));

StringBuffer sb = new StringBuffer("使用BufferedWriter写入文件信息!");

sb.append("\r\n 在创建BufferedInputStream  实例时(BufferedOutputStream同上),需要先给定一个InputStream类型的实例(如:FileInputStream)。");

sb.append("\r\n 解释BufferedInputStream实现流程:其实质是实现了一个缓存装置,在读取源数据的时候其实还是用的InputStream来实现的。只是在读取之前给他们加了一个缓存区而已。");

sb.append("\r\n 注意这个缓存区默认是位数组,大小2048,当读文件的时候,BufferedInputStream会首先填满缓存区,然后在使用InputStream的read()方法的时候,把缓存数组中的数据在读到目的地");

sb.append("\r\n 对BufferedOutputStream,有一个默认512字节的缓存数组,当使用write()方法写数据时,实质上是先将数据写至缓存中,当缓存满时,在用write()方法把数据写入");

byte[] bytes = sb.toString().getBytes();

bos.write(bytes);

bos.flush();

bos.close();

}

/**

* 使用BufferedInputStream

* @throws IOException 

*/

private static void getFileByBufferedInputStream(File file) throws IOException {

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 

byte[] buffer = new byte[bis.available()];

int length = 0;

StringBuffer sb = new StringBuffer(0);

System.out.println("===============BufferedInputStream开始读取文件===================");

while((length=bis.read(buffer,0,buffer.length))!=-1){

System.out.println(new String(buffer));

}

System.out.println("===============BufferedInputStream读取文件结束===================");

}

}


本文出自 “HTMLDOM” 博客,转载请与作者联系!

以上是关于Java IO文件流的主要内容,如果未能解决你的问题,请参考以下文章

java中怎么用io流读写文件

Java编程基础之IO流

Java IO流:节点流(文件流)之 FileInputStream

Java之 IO流字符流字节流缓冲流对象流等各种流

java io流

Java IO—基本文件字符流FileWriterFileReader