Java 字符流操作
来源:互联网 发布:淘宝淘宝联盟怎么用法 编辑:程序博客网 时间:2024/06/05 04:11
上篇文章Java 字节流操作介绍了java中基本的字节流操作,但是我们常常对于字符操作,如果使用字节流来实现输入输出就显得麻烦,我们可以使用字符流来实现对我们看得见的字符char进行操作,主要内容如下:
- 基本流(Reader/Writer)
- 转换流(InputStreamReader/OutputStreamEWriter)
- 文件字符流(FileReader/FileWriter)
- 字符数组流(charArrayReader/charArrayWriter)
- 缓冲字符流(BufferedReader/BufferedWriter)
- 装饰类(PrintWriter)
一、基本流
字节流的基本流是InputStream/OutputStream,这里的字符流的基本流是Reader/Writer,他们都是抽象类,想要实现更加复杂的操作就必须要子类来扩充。他们内部主要的就是read和write方法,实现单个字符及字符数组的读取的写入。此处就不再列出,我们将会从他们的子类中看看这些方法的实现。
二、转换流
InputStreamReader和OutputStreamWriter这两个类型流,在整个字符流中是十分重要的流,他们实现了和字节流的转换。先看看InputStreamReader:
private final StreamDecoder sd;public InputStreamReader(InputStream in)public InputStreamReader(InputStream in, String charsetName)public InputStreamReader(InputStream in, Charset cs)public InputStreamReader(InputStream in, CharsetDecoder dec)public int read() throws IOException { return sd.read(); }public int read(char cbuf[], int offset, int length) throws IOException { return sd.read(cbuf, offset, length); }
首先定义了一个StreamDecoder 类型的常量(这是一个十分重要的成员),一堆构造方法通过不同的方式指定了外部传入的InputStream类型的参数和解码类型。我们看到,read方法中调用的是上述的sd常量(这是一个StreamDecoder类型的常量)的方法。这个StreamDecoder类实际上完成了将字节转换成char的操作。
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ InputStreamReader inr = new InputStreamReader(new FileInputStream("hello.txt")); char[] chs = new char[100]; inr.read(chs); System.out.println(chs); inr.close(); }}
上述代码展示了如何从文件中按照指定的解码方式读取出字符,OutputStreamWriter几乎是逆操作:
public void write(int c)public void write(char cbuf[], int off, int len)public void write(String str, int off, int len)
可以写int,可以写char数组,还可以写字符串(实际上还是调用了getchars方法获取该字符串的内置char数组,然后调用写数组的方法)。
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream("hello.txt")); ow.write("walker"); ow.close(); }}/*可以明显感知,对字符操作的简单直接*/
三、文件字符流
FileReader和FileWriter两个流,继承的是上述的两个转换流。内部的方法非常简单,只是几个构造方法而已。
public FileReader(String fileName) throws FileNotFoundException { super(new FileInputStream(fileName)); }public FileReader(File file) throws FileNotFoundException { super(new FileInputStream(file)); }public FileWriter(String fileName) throws IOException { super(new FileOutputStream(fileName)); }public FileWriter(String fileName, boolean append) throws IOException { super(new FileOutputStream(fileName, append)); }public FileWriter(File file) throws IOException { super(new FileOutputStream(file)); }
从源代码中可以看出来,这两个文件流完全依赖父类。自己基本没有扩展父类,使用的方法都是父类的。你可以通过传文件的路径或者构建File类作为构造参数传入。
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ FileReader fr = new FileReader("hello.txt"); char[] chars = new char[1024]; fr.read(chars); System.out.println(chars); }}
一样可以达到读取字符的效果,实际上上述代码可以转换为:
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ InputStreamReader ins = new InputStreamReader(new FileInputStream("hello.txt")); char[] chars = new char[1024]; ins.read(chars); System.out.println(chars); }}//因为FIleReader的内部还是通过super调用父类的构造方法
四、字符数组流
和之前介绍的字节数组流类似,都是为了能提高效率防止内存浪费而设计的。看看我们上面的一段代码:
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ FileReader fr = new FileReader("hello.txt"); char[] chars = new char[1024]; fr.read(chars); System.out.println(chars); }}
这段程序其实是不完善的,因为我们默认hello文件中的字符容量小于等于1024,那如果文件足够大,我们势必要创建更大的字符数组(这是一种浪费内存)。我们可以使用字符数组流来实现动态扩容,解决内存空间。上述代码可以改写:
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ FileReader fr = new FileReader("hello.txt"); int x = 0; CharArrayWriter chw = new CharArrayWriter(); while ((x = fr.read()) != -1){ chw.write(x); } System.out.println(chw.toString()); chw.close(); }}
这样,即使文件再大,我们也不会浪费很多内存空间。至于StingReader和StringWriter两个流其实是类似的,因为String的本质是char数组, 所以他们必然也是有数组作为最基本的操作。
五、缓冲字符流
字符的缓冲流和字节的缓冲流是类似的。都是装饰流。
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ BufferedReader bins = new BufferedReader(new FileReader("hello.txt")); BufferedWriter bws = new BufferedWriter(new FileWriter("hello.txt",true)); int x; while ((x = bins.read()) != -1){ System.out.println((char)x); bws.write(x); } }}//缓冲读和缓冲写
六、PrintWriter
这是一个继承与Writer的流,他是一个非常方便的类,可以直接指定文件名作为参数,可以指定编码类型,还支持自动缓冲技术,可以自动转换多种基本类型为字符串形式写入文件中。在我们日常使用写入文件时,可以优先考虑使用该类。
protected Writer out;private final boolean autoFlush;//构造方法public PrintWriter (Writer out) { this(out, false); }public PrintWriter(OutputStream out) { this(out, false); }public PrintWriter(String fileName) throws FileNotFoundException { this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))), false);public PrintWriter(File file) throws FileNotFoundException { this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))), false); }//写入一个character public void write(int c) { try { synchronized (lock) { ensureOpen(); out.write(c); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); } catch (IOException x) { trouble = true; } }//写入一个字符串 public void write(String s) { write(s, 0, s.length()); }//重载print方法public void print(boolean b) { write(b ? "true" : "false"); }public void print(char c) { write(c); }public void print(int i) { write(String.valueOf(i)); }public void println() { newLine(); }public void println(int x) { synchronized (lock) { print(x); println(); } }public void println(String x) { synchronized (lock) { print(x); println(); } }
上述代码中的print和println并非和我们的标准输出流(System.out.println)同义,这里的print表示写入到文件中。
public class Test_InputOrOutput { public static void main(String[] args) throws IOException{ PrintWriter pw = new PrintWriter("hello.txt"); pw.println('x'); pw.close(); }}
使用了PrintWriter写入到文件中,非常的简单方便,可以指定文件路径,File,OutputStream作为构造方法的形参。这一切的转换都封装了,自动提供缓冲流。这是一种比较好的输出流,在之后的使用中,如果遇到输出到文件,应该优先考虑PrintWriter。
本篇文章结束了,这两篇文章是我阅读书籍和博客,加上jdk源代码总结得来,如有错误,望大家指出!
- Java 字符流操作
- Java字符流操作
- java IO流字符流FileReader操作
- java字节流字符流IO操作
- Java IO 字节流 字符流操作
- java IO操作(一)--字符流
- Java基础回顾 : 字符流操作
- java IO 字节流 字符流流操作
- Java字符编码操作
- JAVA中的字符编码操作
- Java的流操作分为字节流和字符流两种。
- java IO操作:字节流与字符流区别
- JAVA IO操作——字节流和字符流
- Java自学--IO操作(2)字节流 字符流
- Java IO操作之字节流和字符流
- Java-I/O操作之字符流、其他常用流
- java IO操作:字节流与字符流区别
- Java IO流——字符流读写操作
- 1008. 数组元素循环右移问题 (20) python篇
- POJ 2485Highways (又一个Prim最小生成树水题)
- SecureCRT 常用快捷键
- 对UIView的hitTest: withEvent: 方法的理解
- 练习题 No.6 最长公共子序(LCS)-附赠最长公共子串
- Java 字符流操作
- 第四周:( LeetCode417 ) Pacific Atlantic Water Flow(c++)
- JS实现弹出框文字居中
- 实现应用软件能够通过运行窗口打开
- Java抽象类
- 基于C++模板 单链表基本操作
- linux下使用ffmpeg将amr转成mp3
- Math.round(11.5)等于多少?Math.round(-11.5)等于多少?
- Linux Centos安装python相关库失败处理方法