IO-字符输入流

硬盘上存取的是二进制的数据,记事本软件对硬盘上.txt文件的二进制数据进行了解析,解析之后是字符串。read()读取硬盘上的二进制数据以整数返回。

在硬盘上的数据怎么体现是不同文件的数据,每一段数据都有一个开始和结束的标示,当硬盘碎片。每一段碎片就有标识,通过标识连续读取数据

输入流,读方式,是把数据读到内存中去,

只有输出流,写方式,是存在刷新flush();

写方式是先将数据存到缓冲区中,在缓存中查表,查表结束之后才把把数据存到目的地当中

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class FileReaderDemo {
 
    /**
     * @param args
     * @throws IOException 
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
     
        writeFile();
        /*
         * 需求:读取一个已有的文本文件,将读到的数据打印到控制台(屏幕)。
         * 思路:
         * 1,应该是将硬盘的数据读去到内存中,使用输入流。
         * 2,操作的数据是文本数据,应该使用字符流更为便捷。
         * 3,即使输入,又是字符,应该是字符输入流:Reader
         * 4,要用到字符输入流的哪个功能对象呢?操作文件的,FileReader 。
         * 
         */
        // 1,创建FileReader对象。 并通过构造函数明确数据源。
        // 创建读取对象,和数据源相关联。
         
        FileReader fr = new FileReader("temp\\demo.txt");
        //2,调用Reader中的read方法,一次读取一个字符。
        /*int ch1 = fr.read();
        System.out.println("ch1="+ch1);//97
        int ch2 = fr.read();
        System.out.println("ch2="+ch2);//98
        int ch3 = fr.read();
        System.out.println("ch3="+ch3);//99
        int ch4 = fr.read();
        System.out.println("ch4="+ch4);//-1
        int ch5 = fr.read();
        System.out.println("ch5="+ch5);//-1*/
        //3,使用循环解决问题。
        int ch = 0;
        while((ch=fr.read())!=-1){
        System.out.println((char)ch);
        }
        //3,必须关闭资源。
        fr.close();
        }
        public static void writeFile() throws IOException{
        FileWriter fw = new FileWriter("temp\\demo.txt");
        fw.write("abcde");
        fw.close();
    }
}

IO-字符输入流_read(char[])

public int read(char[] cbuf)         throws IOException

将字符读入数组。在某个输入可用、发生 I/O 错误或者已到达流的末尾前,此方法一直阻塞。

参数:

cbuf - 目标缓冲区

返回:

读取的字符数,如果已到达流的末尾,则返回 -1

抛出:

IOException - 如果发生 I/O 错误

package cn.itcast.p1.io.filereader;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
public class FileReaderDemo2 {
     
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
     
        /*
         * read(char[]); 
         */
        //1,创建读取流对象和数据源关联。
        FileReader fr = new FileReader("temp\\demo.txt");
        
        //2,创建一个字符数组。用于存储读到字符数据。
        //char[] buffer = new char[1024];//2k字节,一个字符是2个字节,一般定义的都是1024的整数倍。因为硬盘以1024字节为单位进行数据的存储。
        
        char[] buffer = new char[2];
        //3,调用读取流的read(char[]),将读到的字符存储到字符数组中。
        /*int len1 = fr.read(buffer);
        System.out.println("len1="+len1+";"+new String(buffer));
        int len2 = fr.read(buffer);
        System.out.println("len2="+len2+";"+new String(buffer));
        int len3 = fr.read(buffer);
        System.out.println("len3="+len3+";"+new String(buffer));
        int len4 = fr.read(buffer);
        System.out.println("len4="+len4+";"+new String(buffer));*/
        
        //4,循环。
        int len = 0;
        while((len=fr.read(buffer))!=-1){
            System.out.println(new String(buffer,0,len));
        }
        
        fr.close();
    }
 
}

IO-文本复制_1

package cn.itcast.io.p2.copytext;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class CopytTextTest {
 
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
     
        /*
         * 需求: 将d盘中的文本文件复制到e盘中。
         *
         * 思路:
         * 1,既然是复制,必须要有源。
         * 2,对源就是读取,并将读到的字符数据存储到目的中。
         * 3,即用到了读,又用到了写。而且还是字符。说明使用Reader Writer
         * 4,操作都是文件,使用的应该是FileReader,FileWriter.
         *
         */
        copyText2();
    }
         
         
    public static void copyText() throws IOException {
        //1,创建一个字符读取流和指定的源相关联。
        FileReader fr = new FileReader("temp\\CopytTextTest.java");
        //2,确定数据存储的目的。
        FileWriter fw = new FileWriter("temp\\demo_copy.txt");
        //3,读一个写出去。有很多字符,需要循环。 当读取动作返回-1,说明结束。
        int ch = 0;
        while((ch=fr.read())!=-1){
        fw.write(ch);
        }
        //4,关闭资源。 
        fw.close();
        fr.close();
    }
     
}

IO-文本复制_2

 public static void copyText2() {
    /*
     * 复制使用数组缓冲区完成。
     * 
     */
    //1,创建读取流和写入流。
    FileReader fr = null;
    FileWriter fw = null;
    try {
    fr = new FileReader("temp\\CopytTextTest.java");
    fw = new FileWriter("temp\\demo_copy2.txt");
    //定义一个缓冲区数组。
    char[] buf = new char[1024];
    int len = 0;
    while((len=fr.read(buf))!=-1){
        fw.write(buf,0,len);//读取几个就写几个。
    }
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
        if(fw!=null)
    try {
        fw.close();
    } catch (Exception e2) {
        throw new RuntimeException("写入关闭失败");
    }
    if(fr!=null)
        try {
            fr.close();
        } catch (Exception e2) {
            throw new RuntimeException("读取关闭失败");
        }
    }
}

IO-文本复制_图解

创建输入流对象,将流对象与源文件关联。

通过输出流对象在目的地位置创建一个文件。

输入流,和输出流是没啥关系。所以存在了一个缓冲区帮助中转,

输入流读取的数据,存取数据到缓冲区,输出流从缓冲区中写到硬盘中去

IO-字符缓冲区-BufferedWriter

public void newLine()             throws IOException

写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 (‘\n‘) 符。

 
package cn.itcast.io.p3.buffer;
 
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
 
public class BufferedWriterDemo {
 
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
     
        /*
         * 演示BufferedWriter.
         * 缓冲区是对流中的数据进行缓冲的。所以必须要在构造缓冲区时,明确具体的流对象。 
         */
        //1,创建字符输出流对象;
        FileWriter fw = new FileWriter("temp\\buf.txt");
        
        //2,创建缓冲区对象,将流对象传给缓冲区的构造函数。
        BufferedWriter bufw = new BufferedWriter(fw);
        
        for(int x=1; x<=4; x++){
        
        bufw.write(x+"-hehe");
        bufw.newLine();//写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,
        bufw.flush();
        }
        bufw.close();//不用在对fw进行关闭,因为关闭缓冲区的就是在关闭该流。
    }
}

IO-字符缓冲区-BufferedReader

通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。

将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。

通过用合适的 BufferedReader 替代每个 DataInputStream,可以对将 DataInputStream 用于文字输入的程序进行本地化。

package cn.itcast.io.p3.buffer;
 
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
public class BufferedReaderDemo {
     
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
     
        /*
         * 字符输入流缓冲区演示BufferedReader.
         */
        //1,创建字符输入流对象。
        FileReader fr = new FileReader("temp\\buf.txt");
        
        //2,创建字符输入流缓冲区对象。
        BufferedReader bufr = new BufferedReader(fr);
        
        //3,使用BufferedReader的特有方法,一次读一行。
        //String line = bufr.readLine();
        //System.out.println(line);
        String line = null;
        while((line=bufr.readLine())!=null){
        System.out.println(line);
        }
        
        
        bufr.close();
    }
 
}

IO-字符缓冲区-通过缓冲区复制文本文件

package cn.itcast.io.p3.buffercopy;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
 
public class CopyTextByBufferTest {
 
    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
     
    /*
     * 通过缓冲区对文本文件进行复制。
     */
        copyTextByBuffer();
    }
     
    public static void copyTextByBuffer() throws IOException {
        //1,创建流对象和缓冲区对象。
        FileReader fr = new FileReader("temp\\buf.txt");
        BufferedReader bufr = new BufferedReader(fr);
        FileWriter fw = new FileWriter("temp\\buf_copy.txt");
        BufferedWriter bufw = new BufferedWriter(fw);
        //2,对一行文本进行读写。
        String line = null;
        while((line=bufr.readLine())!=null){
        bufw.write(line);
        bufw.newLine();
        bufw.flush();
        }
        bufw.close();
        bufr.close();
    }
}

IO-字符缓冲区-readLine方法的原理

IO-字符缓冲区-MyBufferedReader

缓冲区对流功能的增强,提高流的读写效率。
 
 
package cn.itcast.io.p4.mybuffer;
 
import java.io.IOException;
import java.io.Reader;
 
/**
 * 自定义字符读取缓冲区。
 * @author Administrator
 *
 */
public class MyBufferedReader extends Reader {
 
private Reader r;
/*
 * 其实缓冲区无非就是封装了一个数组对象。
 * 对外提供了对数组中元素的操作。
 */
//定义一个字符数组。作为缓冲存在。
private char[] buf = new char[1024];
//定义了两个变量,一个记录数组的角标。一个记录存储到数组中字符的个数。
private int index = 0;
private int count = 0;
 
public MyBufferedReader(Reader r) {
super();
this.r = r;
}

/**
 * 提供一个一次读一个字符的方法。并返回读到字符。如果读到结尾返回-1.
 * 注意:该方法其实是从缓冲区中进行读取。
 * @throws IOException 
 */

public int myRead() throws IOException{

//当count等于0时,才需要去源中取数据。
if(count==0){
//通过流对象的read(char[])方法从源中取一批数据进数组缓冲区,用count记录存储的个数。
count = r.read(buf);

//每获取一次数据,就要将角标归零。
index = 0;
}
if(count<0)
return -1;
char ch =buf[index];
index++;
count--;

return ch;
}

/**
 * 提供一个一次读一行的方法。内部其实使用的是本类的myRead()方法
 * 完成的,将读到的字符进行缓冲,当读取到的行终止符时,将存储的
 * 字符作为字符串返回。
 * @throws IOException 
 */
public String myReadLine() throws IOException{

/*
 * 其中也需要定义缓冲区。就是用StringBuilder
 */
StringBuilder sb = new StringBuilder();

int ch = 0;

while((ch=myRead())!=-1){

if(ch==‘\r‘){
continue;
}
if(ch==‘\n‘){
return sb.toString();
}
sb.append((char)ch);
}

if(sb.length()!=0){
return sb.toString();
}

return null;
}

/**
 * 提供一个关闭资源的方法。
 * @throws IOException 
 */
public void myClose() throws IOException{
//其实就是关闭了流。
r.close();
}
 
 
@Override
public int read(char[] cbuf, int off, int len) throws IOException {

return 0;
}
 
 
@Override
public void close() throws IOException {
}
}
 
 
 
 
package cn.itcast.io.p4.mybuffer;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
 
public class MyBufferedReaderDemo {
 
/**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {
 

FileReader fr = new FileReader("temp\\buf.txt");

MyBufferedReader myBufr = new MyBufferedReader(fr);

String line = null;
while((line=myBufr.myReadLine())!=null){
System.out.println(line);
}

myBufr.myClose();

}
 
}

IO-字符缓冲区-装饰设计模式

package cn.itcast.io.p5.wrapper;
 
public class WrapperDemo {
 
/**
 * @param args
 */
public static void main(String[] args) {
 
Person p = new Person();
//NewPerson p = new NewPerson();
NewPerson pp = new NewPerson(p);
pp.chifan();

/*
 * 装饰模式:为了解决给类的功能进行增强而出现的。
 * 
 * Writer
 * |--TextWriter
 * |--MediaWriter
 * 
 * 想要对流对象的功能进行增强,比如提高写入的效率。
 * 使用缓冲技术。
 * Writer
 * |--TextWriter
 * |--BufferedTextWriter
 * |--MediaWriter
 * |--BufferedMediaWriter
 * 
 * 每一个子类这样实现是可以的,但是导致继承体系较为臃肿。
 * 发现其实无论哪个子类需要高效,使用的都是缓冲技术。
 * 干脆将缓冲技术进行单独的描述和封装。
 * 要缓冲区谁,就将谁传给缓冲区。
 * BufferdWriter
 * 
 * class BufferedWriter extends Writer
 * {
 * BufferedWriter(Writer w)
 * {}
 * }
 * 
 * 装饰设计模式。
 * Writer
 * |--TextWriter
 * |--MediaWriter
 * |--BufferedWriter
 * 
 * 装饰类和被装饰的特点:
 * 1,装饰类中的构造函数需要接受被装饰类。
 * 2,装饰类和被装饰类应该所属于同一个体系。
 * 
 */
}
 
}
 
class Person{
void chifan(){
System.out.println("吃饭");
}
}
 
class NewPerson{

private Person p ;
NewPerson(Person p){
this.p = p;
}

public void chifan(){

System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");

}
}
 
 
 
 
/*
class NewPerson extends Person{
 
@Override
void chifan() {

System.out.println("开胃酒");
super.chifan();
System.out.println("甜点");
System.out.println("来一根");

}

}

IO-字符缓冲区-LineNumberReader

package cn.itcast.io.p6.linenumber;
 
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
 
public class LineNumberReaderDemo {
 
/**
 * @param args
 * @throws FileNotFoundException 
 */
public static void main(String[] args) throws IOException {
 
/*
 * 演示LineNumberReader。
 */
FileReader fr = new FileReader("temp\\CopytTextTest.java");
LineNumberReader lnr = new LineNumberReader(fr);
String line =  null;
lnr.setLineNumber(100);
while((line=lnr.readLine())!=null){
System.out.println(lnr.getLineNumber()+":"+line);
}
lnr.close();
}
 
}
时间: 2024-10-13 14:42:09

IO-字符输入流的相关文章

【IO流】25 - 字符流 - 字符输出流的缓冲流以及字符输入流的缓冲流BufferedWriter和BufferedReader

package cn.itcast.demo2; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; /* * 字符输出流缓冲区流 * java.io.BufferedWriter 继承 Writer * 写入方法 write () 单个字符,字符数组,字符串 * * 构造方法: * BufferedWriter(Writer w)传递任意字符输出流 * 传递谁,就高效谁 *

IO流之字符输入流,字符输出流

在我们日常开发中,我们经常会遇到要上传文件的操作,实现这个都是通过IO流去实现的,这次写的是普通字符输入流和普通输出流,由于效率有点低所以我们在日常开发中不会用到. 所以这次的代码可能只是帮助到接触到java  IO流的初学者,在后面的文章我们会更新高效流文件流 注意:字符流只能用来传输文本文件,所以我们要实现所有类型复制还是要用字节流,字符流的底层也是用到字节流 话不多说直接上代码 字符输入流 public static void main(String[] args) throws IOEx

Java: IO 字符流

FileInputStream和FileOutputStream分别是InputStream和OutputStream的子类,都是字节流.下面例子中有三个方法可以读写字节流: 1.一个一个的 2.一组一组的,可以自定义字节数组的长度 3.使用available方法,可以返回目标文件的长度从而利用该特性建立一个刚刚好长度的字节数组.但该方法有使用风险,例如目标文件过大,一个电影或者一个大数据文件,则会导致超过虚拟机内存的大小,从而出现错误.所以使用该方法要评估风险,如果可以确定目标是小文件,则可以

字符输入流读取文本文件【Reader、FileReader、BufferedReader 】

字符输入流读取文本文件 1.Reader类(读取字符流的抽象类) ※Reader类的常用方法 方法名称 说明 int read() 从输入流中读取单个字符 int read(byte[] c) 从输入流中读取c .length长度的字符,保存到字节数组c中,返回实际读取的字符数 int read(byte[] c, int off , int len) 从输入流中读取最多len长度的字节,保存到字节数组c中,保存的位置从off开始,返回实际读取的字符数 void close() 关闭流 2.字符

转换流:字节输入流转换成字符输入流 InputStreamReader

/* * 将字节输入流变成字符输入流 类 InputStreamReader * 构造方法: * InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader. 常用方法: 方法摘要 void close() 关闭该流并释放与之关联的所有资源. String getEncoding() 返回此流使用的字符编码的名称. int read() 读取单个字符. int read(char[] cbuf, int offset, int

java 21 - 3 字符输入流

所谓的输入流,就是读取文件中的数据 同样的,字符输入流InputStreamReader 4个构造方法,不过2个比较常用: 构造方法: A:InputStreamReader(InputStream is):用默认的编码读取数据B:InputStreamReader(InputStream is,String charsetName):用指定的编码读取数据 A:InputStreamReader(InputStream is):用默认的编码读取数据 InputStreamReader isr =

Reader字符输入流和InputStreamReader和FileReader

1.FileReader  extends InputStreamReader extends Reader 其中,Reader字符输入流和InputStreamReader和FileReader为字符输入流——写出——读取: 原文地址:https://www.cnblogs.com/wmqiang/p/10798538.html

【java】io流之字符输入流:java.io.Reader类及子类的子类java.io.FileReader

1 package 文件操作; 2 3 import java.io.File; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.io.Reader; 7 8 public class TestReader { 9 public static void main(String[] args) throws IOException { 10 File file=new File("D:"+F

java IO之输入流——InputStream

java的基本输入流是java.io.InputStream,该抽象类定义了输入流的基本输入操作方法,实现自该抽象类的子类都有定义自己的数据源,例如ByteArrayInputStream的构造函数指定了ByteArrayInputStream输入流的数据源必须是一个字符数组.这就可以有多种不同的数据源,包括:字符数组.String对象.文件."管道".一个由其他种类的流组成的序列... 1 public ByteArrayInputStream(byte buf[]) {} 2 3

Java IO字符流与字节流

一.基本概念 流:从一端流向另一端,从源头到目的地. 始终与程序为中心,都是程序与文件|数组|网络连接|数据库进行操作. 二.IO流分类 1.流向: 输入流和输出流 2.数据: 字节流:二进制,可以处理文本文件,视频,音频等 . 字符流:文本文件,只能处理纯文本,全款为可见字符(.txt..html). 3.功能: 节点:包裹源头 处理:增强功能,提高性能. 三.字节流与字符流 1.字节流 输入流:InputStream int read(byte[] b) int read(byte[] b,