Java:IO流之字符流Reader、Writer详解

简介:
java.io包中:字符流
  字符流的两个抽象基类:
  Reader         Writer
 
文件的读取:Reader抽象类(java.io包中)
直接子类的构造方法:
FileReader(File file) 
            在给定从中读取数据的 File 的情况下创建一个新 FileReader。 
FileReader(FileDescriptor fd) 
            在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。 
FileReader(String fileName) 
            在给定从中读取数据的文件名的情况下创建一个新 FileReader。 
 
int read()读取单个字符  
   注意:作为整数读取的字符,范围在0到65535之间(0x00-0xffff),如果已到达流的末尾,则返回 -1 
int read(char[] cbuf)  将字符读入数组。
   注意:读取的字符数,如果已到达流的末尾,则返回 -1 
//例子1:使用read()读取单个字符并输出
复制代码
import java.io.*;
class FileReaderDemo
{
    public static void sop(Object obj)
    {
        System.out.print(obj);
    }
    public static void main(String[] args)throws IOException
    {
      //创建一个文件读取流对象,和指定名称的文件相关联起来。
      //要保证该文件是已经存在的。如果不存在,会发生异常,即FileNotFoundException    
      FileReader fr = new FileReader("F:\\myfile\\test.txt");
      
      //调用读取流对象的read方法。
      //read方法:一次读取一次字符,而且会自动往后面读取字符。
      int ch = 0;
      while((ch=fr.read())!=-1)
      {
          sop((char)ch);
      }
     
     /*
     while(true)
      {
        int ch = fr.read();
        if(ch==-1)
            break;
         sop((char)ch);  //读取文件中的一个字符 
      }
    */
      fr.close();
    }
}
复制代码
//例子2:使用read(char[] cbuf)  将字符读入数组再输出
复制代码
import java.io.*;
class FileReaderDemo2
{
    public static void sop(Object obj)
    {
        System.out.print(obj); 
    }
    public static void main(String[] args)throws IOException
    {
      //创建一个文件读取流对象,和指定名称的文件相关联起来。
      //要保证该文件是已经存在的。如果不存在,会发生异常,即FileNotFoundException    
      FileReader fr = new FileReader("F:\\myfile\\test.txt");
      
      //定义一个字符数组,用于存储读取的字符
      char[] buf = new char[1024];
      int num = 0;
      while((num = fr.read(buf))!=-1)//num = fr.read(buf)返回是读取的字符个数,如果已到达流的末尾,则返回 -1 
      {
        //String(char[] value, int offset, int count) 分配一个新的 String,它包含取自字符数组参数一个子数组的字符。
        String str = new String(buf,0,num);
        sop(str);
      }

      fr.close();      
    }

}
复制代码
 
那么再学习字符写入流的特点:Writer 抽象类(java.io包中)    
FileWriter(File file)   根据给定的 File 对象构造一个 FileWriter 对象。
既然IO流是用于操作数据的,那么数据的最常见体现形式是:文件
那么先以操作文件为主来显示。
 
需求:在硬盘上,创建一个文件夹并写入一些文字数据。后缀名是父类名,前缀名是该流对象的功能。
找到一个专门用于操作文件的Writer子类对象。
 
public abstract void close()
       throws IOException关闭此流,但要先刷新它。在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException。
  关闭以前关闭的流无效。
abstract  void flush() 
          刷新该流的缓冲。
//例子3:
复制代码
import java.io.*;
class FileWriterDemo
{
    public static void main(String[] args) throws IOException
    {
        //第一步:
        //创建一个FileWriter对象,该对象一被初始化就必须有明确的被操作的文件,而且该文件会被创建到指定的目录下
        //如果该目录下已有同名文件,将会被覆盖。其实该步就是要明确数据要存放的目的地。
        FileWriter fw = new FileWriter("F:\\myfile\\demo.txt");
        
        
        //第二步:
        //调用父类共性方法write方法,将数据写入到了流当中。
        fw.write("asjdsjdfkskidkf,fdhjsdkjfdsk,dfhjdskj");
        
        //第三步:
        //调用父类共性方法flush方法,刷新流对象中的缓冲中的数据,将数据刷新到目的地中。
        fw.flush();
        
        //可以接着往目的地中写入数据
        fw.write("xiayuanquan");
        fw.flush();
        
        //父类中的共性方法close方法,关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据,将数据刷新到目的地中去。
        //和flush的区别:flush刷新后,流可以继续使用;而close刷新后,流会关闭,无法继续使用。
        fw.write(" aaaaaaaaaaaaaa");
        fw.close(); //Stream closed
        //fw.write("xxxx"); //流已关闭,此时不能再向目的地的文件中写入数据
        
    }
}
复制代码
 
使用字符流读取和写入数据时,可能会出现流异常的情况,例如文件不存在、路径错误等,此时,需要我们对异常进行捕获并处理。
//例子4:
复制代码
import java.io.*;
class FileWriterExceptionDemo
{
    public static void main(String[] args)
    {
        FileWriter fw = null;
        try
        {
            fw = new FileWriter("F:\\myfile\\Exception.txt");//创建目标文件
        
            fw.write("my name is xiayuanquan!"); //往流里写入数据内容
        }
        catch(IOException ie)
        {
            System.out.println(ie.toString());
        }
        finally
        {
            try
            {
              if(fw!=null)    
                fw.close(); //先刷新流,将流中的数据内容刷到目标文件中,然后关闭流资源
            }
            catch(IOException ie)
            {
            System.out.println(ie.toString());
            }
        }
    }
}
复制代码
 
拓展:当用户想把数据写入同一个文件,可是文件中已经存在内容时,那么新写入的数据会替换之前的数据。此时,这不是用户所希望的,针对这种情况,我们可以将新写入的内容在文件内容后面续写即可。api中就提供了一个方法如下:
对已有文件数据内容的续写:
FileWriter(File file, boolean append) 
          根据给定的 File 对象构造一个 FileWriter 对象。
//例子5:
复制代码
import java.io.*;
class FileWriterDemoappend
{
    public static void main(String[] args)
    {
        FileWriter fw = null;
        try
        {
            //传递一个ture参数,代表不覆盖已有的文件。并在已有文件的末尾处进行文件的续写。
            fw = new FileWriter("F:\\myfile\\demo.txt",true);
            fw.write(",,,wei-zhong-hua-jue-qi-er-du-shu");
            fw.write("\r\nabc=abc");//'\r\n'代表换行,然后接着续写数据
        }
        catch(IOException e)
        {
            System.out.println(e.toString());
        }
        finally
        {
            try
            {
                if(fw!=null)
                    fw.close();
            }
            catch(IOException e)
            {
            System.out.println(e.toString());
            }
        }
    }
}
复制代码
 
综合练习:将相同目录下一个文本文件赋值到另一个文本文件中。
(例如:将F:\\myfile\\practice.txt--------->F:\\myfile\\test.txt)
思路:第一步,创建读取流与F:\\myfile\\practice.txt相关联。
         第二步,将F:\\myfile\\practice.txt中数据内容全部读入流中,并放在定义的数组内,然后关闭资源。
         第三部,创建写入流与F:\\myfile\\test.txt相关联,并设置续写功能的布尔值为true;
         第四部,将第二部定义的数组的数据内容全部写入F:\\myfile\\test.txt文件中,然后关闭资源。
//例子6:
复制代码
import java.io.*;
class CopyText
{
    public static void main(String[] args)throws IOException
    {
          FileReader fr = new FileReader("F:\\myfile\\practice.txt");
        FileWriter fw = new FileWriter("F:\\myfile\\test.txt",true);
        
        //第一种方式:(先全部读完数据后存入缓冲区,再一次性续写入目标文件中)
        int num=0;
        char[] buf = new char[1024];
        while((num = fr.read(buf))!=-1)
        {
            String str = new String(buf,0,num);
            fw.write("\r\n"+str);
                // fw.write(buf,0,num);
            fw.close();
        }
        fr.close();
        
        /*
        //第二种方式:(每次读一个数据,就往目标文件中写入一个数据)
        int num = 0;
        while((num = fr.read())!=-1)
        {
            fw.write(num);
        }
        fw.write("\r\n");
        fw.close();
        fr.close();
        */
    }
}
复制代码

 

 
 
程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!
本文转自当天真遇到现实博客园博客,原文链接:http://www.cnblogs.com/XYQ-208910/p/4917923.html ,如需转载请自行联系原作者
相关文章
|
29天前
|
Java
java 中 IO 流
Java中的IO流是用于处理输入输出操作的机制,主要包括字节流和字符流两大类。字节流以8位字节为单位处理数据,如FileInputStream和FileOutputStream;字符流以16位Unicode字符为单位,如FileReader和FileWriter。这些流提供了读写文件、网络传输等基本功能。
50 9
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
91 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
43 1
|
2月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
110 1
|
2月前
|
Java
Java 中 IO 流的分类详解
【10月更文挑战第10天】不同类型的 IO 流具有不同的特点和适用场景,我们可以根据具体的需求选择合适的流来进行数据的输入和输出操作。在实际应用中,还可以通过组合使用多种流来实现更复杂的功能。
66 0
|
2月前
|
存储 Java 程序员
【Java】文件IO
【Java】文件IO
42 0
|
1天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
3天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
3天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
3天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
19 3