在编程中,数据存储是首要任务。在以前的学习中,所有程序中的数据都临时存储在内存中,无法有效存储和长期存储。文件流暂时解决了数据无法长期存储的问题(虽然数据库存储将在以后学习,但文件流存储也非常常见)。
需要注意的是,无论是读取文件还是写入文件,它都是以计算机中流动的形式操作的,就像水的流动一样。从内存本身的角度来看,内存向外写是写作操作,从文件读取到内存是读取操作。输入流和输出流之间的区别:以内存为参考。如果数据流向内存,则为输入流,否则为输出流。
IO流分为字节流和字符流,详细分类如图所示:
字节流和字节流的主要区别在于每次读取数据的大小不同。读取字节流时,读取字节后返回字节。字节流可以处理图片、MP3、AVI视频文件等所有类型的数据,而字节流只能处理字符数据,每次读取一个字符大小。但只要是处理纯文本数据,就要优先使用字符流,除了字节流。字节输入流类包括:FileInputStream、bufferedinputstream和DataInputStream;字节输出流类包括:FileOutputStream、bufferedoutstreamDataOutputStream。字符流输入类:FileReader:方便读取字符文件;字符流输出类:FileWriter:用于写字符文件的方便类,可用于写字符流。由此可见,Stream的流是字节流,而Reader或Writer的流是字符流。具体流量的使用场景如下图所示:
流分类
使用分类
字节输入流
字节输出流
字符输入流
字符输出流
抽象基类
InputStream
OutputStream
Reader
Writer
节点流
访问文件
FileInputStream
FileOutStream
FileReader
FileWriter
访问数值
ByteArrayInputStream
ByteArrayOutStream
CharArrayReader
CharArrayWriter
访问管道
PipedInputStream
PipedOutStream
PipedReader
PipedWriter
访问字符串
StringReader
StringWriter
处理流
缓冲流
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
转换流
InputStreamReader
OutputStreamWriter
对象流
ObjectInputStream
ObjectOutputStream
抽象基类(过滤)
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
打印流
PrintStream
PrintWriter
推回输入流
PushbackInputStream
PushbackReader
特殊流
DataInputStream
DataOutputStream
接下来,详细解读文件字节流的FileinputStream、FileoutPutStream、文件字符流Filewriter和Filerereader。FileinputStream流称为文件字节输入流,即以字节的形式读取文件数据,FileInputStream()结构函数需要输入一个文件对象来指定读取的具体文件。在fileinputstre中读取文件的方法是read(),可以输入自定义大小的byte[]数组。读取的字节数为-1。
Fileoutputstream流是指文件字节输出流,专门用于输出图像数据等原始字节流。它继承了outputstream类,具有输出流的基本特性。FileOutputStream()结构函数还需要传输到文件对象中,Fileoutputstream中的文件写入方法是write(),也可以传输到byte[]数组。注:写入数据后,需要使用close()关闭流。
FileWriter:便利类用于写入字符文件。这种结构方法可以设置默认字符编码和默认字节缓冲区。FileWriter被称为文件字符输出流,FileWriter也需要输入文件对象,但与字节输出流不同的是,字符流的write()方法可以直接输入字符串,为了确保文件中的数据需要使用flush()刷新或直接关闭流,两者之间的区别在于,使用close()后,仍然可以操作对流,但不能再操作该流。
FileReader:便利类用于读取字符文件。假设默认字符编码和默认字节缓冲区的大小是合适的。Filereader被称为文件字符输入流,Filereader也需要输入一个文件对象,但与字节输入流不同的是,字符流的read()方法可以直接输入字符数组,使用后必须使用close()释放资源。
在这里,我们来谈谈文件流操作中最常见的中文乱码问题。1:存储和取出的编码方式不同,会产生中文代码混乱。例如,设置对象的存储代码是GBK代码,而IDEA集成开发环境默认为UTF-8,读取的数据将是随机代码显示。2:使用字节流读取中文文件会产生中文代码,英文字母和数字不会产生代码,因为字节流读取是根据字节读取的,英文字母和数字只占用一个字节,像分割一样,读取一个,UTF-8中文由三个字节组成,所以这样的中文应该是三个字节形成一个汉字,读取分为三个小部分,单独显示就是看不懂的乱码。测试代码如下:public class IoDemo8 { public static void main(String[] args) { String s = “abc”; byte[] bytes = s.getBytes(); String s1 = null; try { // 如果存取时的编码方式不同,中文乱码就会产生 s1 = new String(bytes,"GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println(s1); try { PrintWriter printWriter = new PrintWriter("test.txt"); printWriter.print(“haha拜”; printWriter.flush(); printWriter.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } try { // 使用字节流读会产生中文乱码 FileInputStream fileInputStream = new FileInputStream("test.txt"); int flag = 0; while((flag = fileInputStream.read()) !=-1) { System.out.println((char)flag); } fileInputStream.close(); } catch (Exception e) { e.printStackTrace(); } }}
运行结果:
public class IoDemo2 { public static void main(String[] args) throws Exception { List
运行结果:
到目前为止,已经阐述了文件流的基本知识和应用。学完知识,喝一口鸡汤暖心提神。代码之路,bug无穷,要么出彩,要么出局!