[Thinking in Java] - No.10 Stream、File和IO(2):Stream和IO初探
2017-09-27 21:09
477 查看
IO中经常会使用到的概念是“流”。在IO中,有两种流,分别对应字符流和字节流。
字节流: Java中的字节流处理的最基本单位为单个字节。
字符流:Java中的字符流处理的最基本的单元是Unicode码元。
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据。但它不支持直接写入或读取Unicode码元,所以使用字节流处理中文常常会乱码。字符流通常处理文本数据,它支持写入及读取Unicode码元。
字符流在IO的时候会先把数据读写到缓冲区中,然后再写入文本。而字节流则是直接操纵文本。
如何体验出字符流使用缓存而字节流不使用缓存呢?我们看下面的例子
Java中的I/O类库按照字符流和字节流分为以下:
简单的归纳一下:
字符流:使用缓冲区读写-使用Reader/Writer进行IO
字节流:直接操作文本-使用InputStream/OutputStream进行IO
在字符流中,我们常用到:FileReader/FileWriter和BufferReader/BufferWriter
在字节流中,我们常使用:FileInputStream/FileOutputStream和BufferInputStream/BufferOutputStream
字符流:
FileReader/FileWriter使用:
write()函数和append()函数均是向文本中写入,两者本身没没有太大区别,网上普遍认为append是追加,write是复写,这是错误的。因为FileWriter重写与否,是根据构造函数中的参数来确定。
FileWriter源码中:
BufferReader/BufferWriter使用:
mark(int readlimit):调用该函数的时候记录一下标记位置,在下次使用reset()的时候使读取的位置重新回到该标记位置,然后继续往后读。如果在标记以后读取的长度大于readlimit,则上次标记位置失效。
reset():将游标重置到上次标记的位置,重新读取。
字节流:
FileInputStream/FileOutputStream使用:
字符流和字节流的选用:
字节流:硬盘中存储的音频文件、图片、歌曲,所有的硬盘上保存文件或进行传输或者实现拷贝的时候,应该选择字节流
字符流:处理中文使用字节流会乱码。
字节流: Java中的字节流处理的最基本单位为单个字节。
字符流:Java中的字符流处理的最基本的单元是Unicode码元。
字节流通常用于处理二进制数据,实际上它可以处理任意类型的数据。但它不支持直接写入或读取Unicode码元,所以使用字节流处理中文常常会乱码。字符流通常处理文本数据,它支持写入及读取Unicode码元。
字符流在IO的时候会先把数据读写到缓冲区中,然后再写入文本。而字节流则是直接操纵文本。
如何体验出字符流使用缓存而字节流不使用缓存呢?我们看下面的例子
public static void main(String args []) throws IOException{ File file = new File("E:\\test001.txt"); File file1 = new File("E:\\test002.txt"); FileWriter fWriter = new FileWriter(file); FileOutputStream fStream = new FileOutputStream(file1); String str = "Hello World"; fWriter.write(str); fStream.write(str.getBytes()); //fWriter.close(); //fStream.close(); }在上面的例子中,我们注释掉了close()函数,所以两个流均没有关闭。运行程序我们发现。字符流对应的test001没有写入"Hello World",但是字节流对应的test002写入了。我们将程序中两个流均关闭,重新运行函数,两个文本均写入指定字符串。所以我们可以发现,字节流是直接操纵文本,字符流则是通过缓冲区操纵文本,同时在close()函数或者flush()执行的时候写入文本。
Java中的I/O类库按照字符流和字节流分为以下:
简单的归纳一下:
字符流:使用缓冲区读写-使用Reader/Writer进行IO
字节流:直接操作文本-使用InputStream/OutputStream进行IO
在字符流中,我们常用到:FileReader/FileWriter和BufferReader/BufferWriter
在字节流中,我们常使用:FileInputStream/FileOutputStream和BufferInputStream/BufferOutputStream
字符流:
FileReader/FileWriter使用:
File file = new File("E:\\class.txt"); FileReader fileReader = new FileReader(file); char[] cbuf = new char [1000]; fileReader.read(cbuf); for(char c:cbuf) { System.out.print(c); } FileWriter fWriter = new FileWriter(new File("E:\\test123.txt"),true); fWriter.write("123456"); fWriter.write("nihaoa");Reader和Writer的函数都很简单可以自行查看。这里注意两个函数:write()函数和append()函数。
write()函数和append()函数均是向文本中写入,两者本身没没有太大区别,网上普遍认为append是追加,write是复写,这是错误的。因为FileWriter重写与否,是根据构造函数中的参数来确定。
FileWriter源码中:
public FileWriter(File file, boolean append) throws IOException { super(new FileOutputStream(file, append)); }第二个参数决定了重写还是追加。write()和append()源码如下:
public void write(String str) throws IOException { write(str, 0, str.length()); } public Writer append(char c) throws IOException { write(c); return this; }可以发现append()函数本质上直接调用了write(),只是多返回了一个Writer对象的引用。
BufferReader/BufferWriter使用:
Reader re = new FileReader(file); BufferedReader bReader = new BufferedReader(re); bReader.readLine(); Writer writer = new FileWriter(new File("E:\\test123.txt")); BufferedWriter bWriter = new BufferedWriter(writer); bWriter.write("Hello World~"); bWriter.close();BufferReader/BufferWriter也使用了一个缓冲区,减少了一定程度上的IO次数,所以要比Reader/Writer快一些。同时也具有mark()和reset()函数。
mark(int readlimit):调用该函数的时候记录一下标记位置,在下次使用reset()的时候使读取的位置重新回到该标记位置,然后继续往后读。如果在标记以后读取的长度大于readlimit,则上次标记位置失效。
reset():将游标重置到上次标记的位置,重新读取。
字节流:
FileInputStream/FileOutputStream使用:
// 从文件中读取 File file = new File("E:\\class.txt"); InputStream iStream = new BufferedInputStream(new FileInputStream(file)); byte [] bs = new byte [10240]; try { iStream.read(bs); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(new String(bs)); //写入文件 File file1 = new File("E:\\test1.txt"); String str = "HelloWorld"; FileOutputStream fOutputStream = new FileOutputStream(file1); fOutputStream.write(str.getBytes()); fOutputStream.close();BufferInputStream/BufferOutputStream使用类似:
File file = new File("E:\\class.txt"); BufferedInputStream bStream = new BufferedInputStream(new FileInputStream(file)); byte [] bs = new byte [10240]; try { bStream.read(bs); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(new String(bs)); File file1 = new File("E:\\test1.txt"); BufferedOutputStream bStream2 = new BufferedOutputStream(new FileOutputStream(file1)); String str = "HelloWorld~~~"; bStream2.write(str.getBytes()); bStream2.close();注:字节流的类均为Inputstream/OutputStream的子类,所以均实现了mark(int readlimit)和reset()。同时,BufferInputStream/BufferOutputStream比FileInputStream/FileOutputStream效率要高一点。
字符流和字节流的选用:
字节流:硬盘中存储的音频文件、图片、歌曲,所有的硬盘上保存文件或进行传输或者实现拷贝的时候,应该选择字节流
字符流:处理中文使用字节流会乱码。
相关文章推荐
- [Thinking in Java] - No.9 Stream、File和IO(1):File类
- 官网 Java 流(Stream)、文件(File)和IO使用
- Java 流(Stream)、文件(File)和IO
- Java 流(Stream)、文件(File)和IO
- Java 流(Stream)、文件(File)和IO
- Java总结:Java 流(Stream)、文件(File)和IO
- JAVA 流(Stream)、文件(File)和IO
- Java流(Stream)、文件(File)和IO
- Java 流(Stream)、文件(File)和IO
- Java 流(Stream)、文件(File)和IO
- Java 流(Stream)、文件(File)和IO -- Java ByteArrayInputStream类
- javaStream,File和IO
- Java 流(Stream)、文件(File)和IO
- java——流(Stream)、文件(File)和IO
- JAVA基础初探(十三)IO简介、字节流与字符流区别、带缓冲的字节/字符流读取数据、FileReader/FileWriter便捷类、Apache IO库使用说明
- Java 流(Stream)、文件(File)和IO
- Java 流(Stream)、文件(File)和IO
- java_io.FileReaderStream
- Java 流(Stream)、文件(File)和IO
- Java Stream、File、IO