博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

JavaEE - 13IO流

Posted on 2020-12-08 09:29  Kingdomer  阅读(100)  评论(0编辑  收藏  举报

JavaEE - 13IO流

(1)File

  • java.io.File: 文件 和 目录路径名的抽象表示形式,与平台无关
  • File能新建、删除、重命名文件和目录,但File不能访问文件内容本身。访问文件内容,需要使用输入/输出流。
  • 在Java程序表示一个真实存在的文件或目录,必须有一个File对象,但File对象可能没有真实存在的文件或目录。
  • File对象可以作为参数传递给流的构造器。File 类 和 io 流无关,不能通过该类完成文件的读和写。

(1.1)File类常用构造器

  • public File(String pathname):  以pathname为路径创建File对象,可以是绝对路径或相对路径。
    • pathname是相对路径,默认的当前路径在系统属性user.dir中存储。System.out.println(System.getProperty("user.dir"));
    • 绝对路径: 是一个固定的路径,从盘符开始;  相对路径: 相对于某个位置开始
  • public File(String parent, String child): 以parent为父路径, child为子路径创建File对象。
  • public File(File parent, String child):   根据一个父File对象和子文件路径创建File对象
  • 当硬盘中有一个真实的文件或目录存在时,创建File对象时,各个属性会显示赋值。
  • 当硬盘中没有真实的文件或目录时,创建对象,除了指定目录和路径之外,其他的属性都是取成员变量的默认值。

(1.2)路径分隔符

  • 路径中的每级目录之间用一个路径分隔符隔开。
  • 路径分隔符和系统有关: windows和DOS系统默认使用"\"来表示。 UNIX和URL使用"/"来表示。
  • Java程序支持跨平台运行,因此路径分隔符要慎用。
  • 为了解决隐患,File类提供了一个常量:public static final String separator。根据操作系统,动态的提供分隔符。
    @Test
    public void test1(){
        File f1 = new File("test01.txt"); // 构造器1
        File f2 = new File("E:\\app\\test02.txt");
        File f3 = new File("E:\\app\\Tomcat8.5.30\\","abc.txt");  // 构造器2
        File f4 = new File("E:" + File.separator +"app" + File.separator + "abc.txt");
        File f5 = new File("E:\\app");
        File f6 = new File(f5,"h.txt");  //构造器3
        System.out.println(f1); //test01.txt
        System.out.println(f2); //E:\app\test02.txt
        System.out.println(f3); //E:\app\Tomcat8.5.30\abc.txt
        System.out.println(f4); //E:\app\abc.txt
        System.out.println(f6); //E:\app\h.txt
    }

(1.3)File类常用方法

  • public String getAbsolutePath():  获得绝对路径
  • public String getPath():          获取路径
  • public String getName():          获取名称
  • public String getParent():        获取上层文件目录路径。如无,返回null。
  • public long length():             获取文件长度(即:字节数)。不能获取目录的长度。
  • public long lastModified():       获取最后一次的修改时间,毫秒值。
  • public String[] list():           获取指定目录下的所有文件或者文件目录的名称数组
  • public File[] listFiles():        获取指定目录下的所有文件或者文件目录的File数组
    @Test
    public void test2(){
        File file1 = new File("hello.txt");
        System.out.println(file1.getAbsolutePath());  //E:\javaProgramLearn\13FileIO\hello.txt
        System.out.println(file1.getPath());          //hello.txt
        System.out.println(file1.getName());          //hello.txt
        System.out.println(file1.getParent());        //null
        System.out.println(file1.length());           //57
        System.out.println(new Date(file1.lastModified())); //Fri Dec 04 17:44:08 CST 2020
    }

list() 和 listFiles()方法 

    @Test
    public void test3(){
        File file = new File("E:\\javaProgramLearn\\13FileIO");
        String[] list = file.list();
        for(String s : list){
            System.out.println(s);  // 13FileIO.iml  hello.txt  src(目录)
        }

        File[] files = file.listFiles();
        for(File f : files){
            // E:\javaProgramLearn\13FileIO\13FileIO.iml  E:\javaProgramLearn\13FileIO\hello.txt E:\javaProgramLearn\13FileIO\src      
            System.out.println(f);
        }
    }

 

  • pubilc boolean renameTo(File dest):把文件重命名到指定的文件路径下。
    • 比如:file1.renameTo(file2): 保证返回true, 需要file1在硬盘中存在,且file2在硬盘中不存在。
  • public boolean isDirectory():   判断是否是文件目录
  • public boolean isFile():        判断是否是文件
  • public boolean exists():        判断是否存在
  • public boolean canRead():       判断是否可读
  • public boolean canWrite():      判断是否可写
  • public boolean isHidden():      判断是否隐藏
  • public boolean canExecute():    判断是否可执行
    @Test
    public void test4(){
        File file1 = new File("hello.txt");
        File file2 = new File("E:\\app\\hi.txt");
        boolean renameTo = file1.renameTo(file2);
        System.out.println(renameTo); 
    }

    @Test
    public void test5(){
        File file = new File("E:\\app"); 
        System.out.println(file.isDirectory()); // true
        System.out.println(file.isFile());      // false
        System.out.println(file.exists());      // true
        System.out.println(file.canRead());     // true
        System.out.println(file.canWrite());    // true
        System.out.println(file.isHidden());    // false
    }

 

  • File类的创建功能
    • public boolean createNewFile(): 创建文件。若文件存在,则不创建,返回false
    • public boolean mkdir():  创建文件目录。若文件目录存在,就不创建了,如果文件目录的上层目录不存在, 也不创建。
    • public boolean mkdirs(): 创建文件目录。如果上层目录不存在,一并创建。
    • 注意: 创建文件或文件目录时没有写盘符路径,默认在项目路径下。
  • File类的删除功能
    • public boolean delete(): 删除文件或者目录
    • 注意:Java中删除不走回收站。要删除一个文件目录,该文件目录不能包含文件或目录。
    @Test
    public void test6() throws IOException {
        File file = new File("hello.txt");
        if(!file.exists()){
            file.createNewFile();
            System.out.println("创建成功");
        }else{
            System.out.println("文件已存在");
        }

        File file1 = new File("E:\\javaProgramLearn\\13FileIO\\test1\\test2");
        boolean mkdir = file1.mkdir();
        if(mkdir){
            System.out.println("创建目录成功");
        }else{
            System.out.println("创建目录失败");
        }

        File file2 = new File("E:\\javaProgramLearn\\13FileIO\\test1\\test2");
        boolean mkdir2 = file2.mkdirs();
        if(mkdir2){
            System.out.println("创建目录成功");
        }else{
            System.out.println("创建目录失败");
        }
    }

使用递归,找出某目录下所有 子目录及其文件

    public static void method1(File f) {
        if (f.isFile()) {
            System.out.println(f.getAbsolutePath();
        }
        if (f.isDirectory()) {
            File[] fs = f.listFiles();
            for (File subFile : fs) {
                System.out.println(subFile.getAbsolutePath());
                method1(subFile);
            }
        }
    }

    @Test
    public void test7(){
        File f = new File("E:\\javaProgramLearn");
        method1(f);
    }

找出指定目录下以特定后缀的文件

    @Test
    public void test8(){
        File f = new File("E:\\javaProgramLearn");
        method2(f);
    }

    public static void method2(File f) {
        if (f.isFile() && f.getAbsolutePath().endsWith(".java")) {
            System.out.println(f);
        }
        if (f.isDirectory()) {
            File[] fs = f.listFiles();
            for (File subFile : fs) {
                method2(subFile);
            }
        }
    }

 

(2)IO流原理及流的分类

(2.1)Java IO原理

  • I/O是Input/Output的缩写,I/O技术用于处理设备之间的数据传输。如读写文件、网络通讯等。
  • Java程序中,对于数据的输入/输出操作以"流(stream)"的方式进行。
  • java.io包下提供了各种"流"类和接口,用于获取不同种类的数据,并通过标准的方法输入或输出数据。
  • 输入输出
    • 输入input:  读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。 
    • 输出output: 将程序(内存)数据输出到磁盘、光盘等存储设备中。

(2.2)分类

  • 按操作数据单位不同分为:  字节流(8bit)、字符流(16bit)
  • 按数据流的流向不同分为:  输入流、输出流
  • 流的角色的不同分为:   节点流、处理流
  • Java的IO流共涉及到40多个子类,实际上非常规则,都是从4个抽象基类派生的。
  • 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
分类
字节输入流
字节输出流
字符输入流
字符输出流
抽象基类
InputStream
OutputStream
Reader
Writer
访问文件
FileInputStream
FileOutputStream
FileReader
FileWriter
访问数组
ByteArrayInputStream
ByteArrayOutputStream
CharArrayReader
CharArrayWriter
访问管道
PipedInputStream
PipedOutputStream
PipedReader
PipedWriter
访问字符串
   
StringReader
StringWriter
缓冲流
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
转换流
   
InputStreamReader
OutputStreamWriter
对象流
ObjectInputStream
ObjectOutputStream
   
 
FilterInputStream
FilterOutputStream
FilterReader
FilterWriter
打印流
 
PrintStream
 
PrintWriter
推回输入流
PushbackInputStream
 
PushbackReader
 
特殊流
DataInputStream
DataOutputStream
   

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

IDEA 下项目与 module 的文件目录路径区别

使用Junit中的单元测试方法测试,相对路径为当前Module下。使用main()测试,相对路径在当前的Project下。

public class FileReaderWriterTest {

    @Test
    public void testFileReader(){
        File file = new File("hello.txt");  // 相对于module
        System.out.println(file.getAbsolutePath()); //E:\javaProgramLearn\13FileIO\hello.txt
    }

    public static void main(String[] args) {
        File file = new File("hello.txt");  // 相对于当前工程
        System.out.println(file.getAbsolutePath());  // E:\javaProgramLearn\hello.txt

        File file2 = new File("13FileIO\\hello.txt");
        System.out.println(file2.getAbsolutePath());  //E:\javaProgramLearn\13FileIO\hello.txt
} }

 

(3)节点流(或文件流)

FileInputStream、FileOutputStream、FileReader、 FileWriter

    @Test
    public void test1() throws IOException {
        // 1. 实例化File对象
        File file = new File("world.txt");
        // 2. 提供具体的流
        FileReader fr = new FileReader(file);
        // 3. read()返回读入的一个字符
//            int data = fr.read();
//            // 如果达到文件末尾,返回-1
//            while(data != -1){
//                System.out.println((char)data);
//                data = fr.read();
//            }
        // 第三步的方式二
        int data2;
        while((data2 = fr.read()) != -1){
            System.out.println((char)data2);
        }
        // 4. 流的关闭
        fr.close();
     }

为了保证流资源一定可以执行关闭操作,需要使用try-catch-finally结构处理

    @Test
    public void test2(){
        FileReader fr = null;
        try{
            // 1. 实例化File对象
            File file = new File("world.txt");
            // 2. 提供具体的流
            fr = new FileReader(file);
            // 3. 数据读入
            int data2;
            while((data2 = fr.read()) != -1){
                System.out.println((char)data2);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            // 4. 流的关闭
            try{
                if(fr != null)
                    fr.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

read(char[] cbuf)

            // read(char[] cbuf):返回每次读入cbuf数组中的字符个数。
            char[] cbuf = new char[5];
            int len;
            while((len = fr.read(cbuf)) != -1){
//                for (int i = 0; i < cbuf.length; i++){
//                    System.out.println(cbuf[i]);  // 会出现多数据情况,最后一组可能不足5,
//                }
                for (int i = 0; i < len; i++){
                    System.out.println(cbuf[i]);  // 正确方式一
                }
                
//                String str = new String(cbuf);      // 会出现多数据情况,最后一组可能不足5,
//                System.out.println(str);
                String str = new String(cbuf,0,len);      // 正确方式二
                System.out.println(str);
            }

FileWriter

  • 文件如果不存在,在输出的过程中,会自动创建此文件。
  • FileWriter(file,false) / FileWriter(file): 如果文件存在,则对原文件进行覆盖
  • FileWriter(file,true): 如果文件存在,不会对原有文件覆盖,而是在原有文件基础上追加内容
    @Test
    public void test3(){
        File file = new File("hello1.txt");
        FileWriter fw = null;
        try {
            fw = new FileWriter(file);  // FileWriter(file,false)  FileWriter(file,true)

            fw.write("第一行one dream");
            fw.write("\n");
            fw.write("第二行to dream");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fw != null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

处理普通文件的拷贝

    @Test
    public void TestReadWrite() throws Exception{
        File sourceFile = new File("hello1.txt");
        File destFile = new File("dest.txt");
        FileReader fr = new FileReader(sourceFile);
        FileWriter fw = new FileWriter(destFile);

        char[] cbuf = new char[5];
        int len;
        while((len = fr.read(cbuf)) != -1){
//            String str = new String(cbuf,0,len);
//            fw.write(str);
            fw.write(cbuf,0,len);
        }
        fr.close();
        fw.close();
    }

普通文件的拷贝(完整版)

    @Test
    public void test4(){
        FileReader fr = null;
        FileWriter fw = null;

        try{
            File sourceFile = new File("hello1.txt");
            File destFile = new File("dest.txt");
            fr = new FileReader(sourceFile);
            fw = new FileWriter(destFile);
            char[] cbuf = new char[5];
            int len;
            while((len = fr.read(cbuf)) != -1) {
                fw.write(cbuf, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try{
                if(fw != null)
                    fw.close();
            }catch (IOException e){
                e.printStackTrace();
            }
            try{
                if(fr != null)
                    fr.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

FileInputStream

    @Test
    public void testFileInputStream(){
        FileInputStream fis = null;
        try{
            File file = new File("world.txt");
            fis = new FileInputStream(file);
            byte[] bytes = new byte[5];
            int len;
            while((len = fis.read(bytes)) != -1){
                String str = new String(bytes,0,len);
                System.out.println(str);  // 存在中文乱码, byte[5]的原因。中文的字节拆分不准确
            }
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fis != null)
                    fis.close();
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
处理特殊文件的:
  • 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
  • 对于非文本文件(.jpg, .mp3, .mp4, .avi, .doc, .ppt,...),使用字节流处理
 @Test
    public void TestFileInputOutStream(){
        FileInputStream fis = null;
        FileOutputStream fos = null;

        File srcPhoto = new File("桌面壁纸.jpg");
        File destPhot = new File("22.jpg");
        try {
            fis = new FileInputStream(srcPhoto);
            fos = new FileOutputStream(destPhot);
            byte[] buffer = new byte[5];
            int len;
            while((len = fis.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

 

(4)处理流: 缓冲流

  • 处理流的一种
    • BufferedInputStream(read(byte[] buffer))、 BufferedOutputStream(write(byte[] buffer,0,len))
    • BufferedReader(read(byte[] cbuf)/readLine())、BufferedWriter(write(char[] cbuf,0,len))
  • 作用: 提高流的读取、写入的速度;  原因: 内部提供了一个缓冲区
    @Test
    public void TestBufferedFileInputOutStream(){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream(new File("11.jpg")));
            bos = new BufferedOutputStream(new FileOutputStream(new File("33.jpg")));

            byte[] buffer = new byte[5];
            int len;
            while((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        }
        // 省略其他代码,与BufferedReader/BufferedWriter类似
    }

BufferedReader / BufferedWriter

    @Test
    public void TestBufferedFileReadWriteStream(){
        BufferedReader br = null;
        BufferedWriter bw = null;

        try {
            br = new BufferedReader(new FileReader(new File("hello1.txt")));
            bw = new BufferedWriter(new FileWriter(new File("hello2.txt")));

            char[] buffer = new char[1024];
            int len;
            while((len = br.read(buffer)) != -1){
                bw.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

读取一行数据 readLine() 

            String data;
            while ((data = br.readLine()) != null){
                bw.write(data +"\n");  // data中不包含转行符  bw.write(data); bw.newLine();
            }

 

(5)处理流: 转换流

  • 转换流提供了在字节流和字符流之间的转换。
  • JavaAPI提供了两个转换流:
    • InputStreamReader:  将 字节输入流InputStream 转换为 字符输入流Reader
    • OutputStreamWriter: 将Writer转换为OutputStream
  • 字节流中的数据都是字符时,转成字符流操作更高效。
  • 很多时候使用转换流来处理文件乱码问题。实现编码和解码的功能。
  • utf8.txt --字节流--> InputStreamReader(uft-8) --字符流--> 程序 --字符流--> OutputStreamWriter(gbk) --字节流--> gbk.txt
    @Test
    public void test1() throws IOException {
        FileInputStream fis = new FileInputStream("dbcp.txt"); // GBK编码
//        InputStreamReader isr = new InputStreamReader(fis); //使用系统默认的字符集UTF-8
        InputStreamReader isr = new InputStreamReader(fis,"GBK"); //指明字符集,取决文件保存时使用的字符集
        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
            String str = new String(cbuf,0,len);
            System.out.print(str);
        }
        isr.close();
    }

读取GBK格式的文件,转换为UTF格式的文件 

    @Test
    public void test2() throws IOException {
        File file1 = new File("dbcp.txt");
        File file2 = new File("dbcp_utf.txt");

        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);
        InputStreamReader isr = new InputStreamReader(fis,"GBK");
        OutputStreamWriter osw = new OutputStreamWriter(fos);

        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
           osw.write(cbuf,0,len);
        }
        isr.close();
        osw.close();
    }

 

(5.2)字符集

  • ASCII:      美国标准信息交换码。 用一个字节的7位表示。
  • ISO8859-1:  拉丁码表。欧洲码表。 用一个字节的8位表示。
  • GB2312:     中国的中文编码表。   最多两个字节编码所有字符。
  • GBK:        中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码。
  • Unicode:    国际标准码,融合了目前人类使用的所有字符。为每个字符分配了唯一的字符码。
  • UTF-8:      变长的编码方式,可用1-4个字节来表示一个字符。
  • 字符编码
  • Unicode不完美,有三个问题:
    • 一是英文字母只用一个字节就可以表示。
    • 二是如何才能区分Unicode和ASCII?如何判断两个字节表示一个符号,而不是分别表示两个符号?
    • 三是如果和GBK等双字节编码方式一样,用最高位是1或0表示两个字节和一个字节,就少了很多值表示字符,会不够用。
  • 面向传输的UTF(UCS Transfer Format)标准出现,UTF-8就是每次8个位传输数据。UTF-16是每次16个位。这是为传输而设计的编码。
  • Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一的编号。具体存储成什么样的字节流,取决于字符编码方案。
  • 推荐Unicode编码是UTF-8 和 UTF-16。

 

(6)处理流: 标准输入、输出流

  • System.in 和 System.out 分别代表了系统标准的输入和输出设备
  • 默认输入设备是: 键盘;输出设备是: 显示器。
  • System.in  的类型是 InputStream
  • System.out 的类型是 PrintStream, 是OutputStream的子类FilterOutputStream的子类。
  • 重定向: 通过System类的setIn、setOut方法对默认设备进行改变。
    • public static void setIn(InputStream in)
    • public static void setOut(PrintStream out)

    @Test
    public void test1(){
        BufferedReader br = null;
        try{
            InputStreamReader isr = new InputStreamReader(System.in);
            br = new BufferedReader(isr);

            while(true){
                System.out.println("请输入字符串: ");
                String data = br.readLine();
                if("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)){
                    System.out.println("程序结束");
                    break;
                }
                String upperCase = data.toUpperCase();
                System.out.println(upperCase);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(br != null){
                try{
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

System.in

public class SystemInOutTest {

    public static String readString(){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String string = "";
        try{
            string = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return string;
    }

    public static void main(String[] args) {
        String s = readString();
        System.out.println("输入的是:" + s);
    }
}

 

 

 

相对内存来说,
进入内存, 输入 读 出内存 输出

java.io.InputStream 文件字节输入流

【FileInputStream】 按照字节方式读取文件。

// 读取某个文件,先与这个文件 创建一个输入流

FileInputStream fis = null;
try{
String filePath="temp01";
fis = new FileInputStream(filePath);

// 开始读
int i1 = fis.read(); // 97, 以字节方式读取
int i2 = fis.read(); // 98
...
int i7 = fis.read(); // -1 已经读取到文件末尾,返回-1
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOEexception e){
e.printStackTrace();
}
finally{
// 为了保证文件流一定会被释放, 在finally 执行
if(fis!=null){
try{
fis.close();
}
catch(IOException e){
e.printStackTrace();
}

}
}

[第二个例子]
FileInputStream fis = new FileInputStream("temp01");

while(true){
int temp = fis.read();
if(temp == -1) break;
syso(temp);
}
fis.close();
}


int temp = 0;

while((temp=fis.read()) != -1){
syso(temp);
}

缺点: 频繁读取磁盘,效率低

[第三个例子] read(byte[] bytes)
每次读取多个字节,存在byte 数组中。

FileInputStream fis = new FileInputStream("temp01");

byte[] bytes = new byte[3]; // 每一次最多三个字节
int i1 = fis.read(bytes); // 3, 返回的是这次读取的字节数
syso(new String(bytes)); //abc def gef, 第三次有问题,再往后没有数据
int i2 = fis.read(bytes); // 3, 没有返回 -1
int i3 = fis.read(bytes);
syso(new String(bytes,0,i3)); //g,将数组的一部分 转为数组


fis.close();

【第四个例子】

FileInputStream fis = new FileInputStream("temp01");

byte[] bytes = new byte[1024];
while(true){
int temp = fis.read(bytes);
if(temp==-1) break;
syso(new String(bytes,0,temp)); // temp 有效数据部分
}

fis.close();

【升级】

int temp = 0;
while((temp = fis.read(bytes)) != -1){
syso(new String(bytes,0,temp)); // 使用print,不是println
}

【第五个例子】
FileInputStream fis = new FileInputStream("temp01");

syso(fis.avaiable()); //7字节

fis.read();
syso(fis.avaiable()); //7字节,返回流中剩余估计的字节数

// 跳过两个字节
fis.skip(2);
syso(fis.read());
fis.close();

Copy:
创建输入流
FileInputStream fis = new FileInputStream("temp");

FileOutputStream fos = new FileOutputStream("C:/output_temp");

byte[] bytes = new byte[1024];
int temp =0;
while((temp=fis.read(bytes))!= -1){
fos.write(bytes,0,temp);
}


fos.flush();

fis.close();

fos.close();


java.io.Reader
java.io.InputStreamReader 转换流 字节输入流 -> 字符输入流
java.io.FileReader 文件字符输入流


try{
FileReader fr =new FileReader("test.java");

char[] chars = new char[512];
int temp = 0;
while((temp=fr.read(chars)) != -1){
syso(new String(chars, 0, temp));
}

}
catch(Exception e){
e.printStackTrace();
}

finally{
if(fr!= null){
try{
fr.close();
}
catch(Exception e){
e.printStackTrace();
}
}

}

java.io.Writer
java.io.OutputStreamReader 转换流 字节输出流 -> 字符输出流
java.io.FileWriter 文件字符输出流

try{
FileWriter fw =new FileWriterr("test.java"); //覆盖
FileWriter fw =new FileWriterr("test.java",true); // 追加

fw.write("ssssssssssssssssssss");

char[] chars = {'我', '是'};
fw.write(chars, 0, 5);
}
catch(Exception e){
e.printStackTrace();
}

finally{
if(fr!= null){
try{
fr.close();
}
catch(Exception e){
e.printStackTrace();
}
}

}


复制: 只能复制纯文本文件

FileReader fr = new FileReader("copy.java");

FileWriter fw = new FileWriter("c:/copy2.java");


char[] chars = new char[512];

int temp = 0;

while((temp = fr.read(chars)) != -1){
fw.write(chars,0,temp);
}

fw.flush();

fr.close();
fw.close();

带有缓冲区的
BufferedInputStream
BufferedOutputStream
BufferedReader 字符输入流
BufferedWriter 字符输出流


// 创建一个带缓冲区的字符输入流
FileReader fr = new FileReader("test.java"); // 文件字符输入流
BufferedReader br = new BufferedReader(fr); //将文件字符输入流 包装成带有缓存区的

根据流出现的位置, 分为 包装流或者处理流 br 和 节点流 fr。


BufferedReader br = new BufferedReader(new FileReader("test.java"));

String temp = null;
while((temp=br.readLine()) != null){
syso(temp); // print 输出一行 ,不带换行符
}
// br.readLine() 读取一行, 行尾不带换行符

// 关闭
只需要关闭最外层的包装流, 装饰者模式。

br.close();


第二个例子

FileInputStream fis = new FileInputStream("xxx.java"); // 文件字节输入流
// 转换流 将字节流转换成字符流
InputStreamReader isr = new InputStreamReader(fis); // isr 是字符流

BufferedReader br = new BufferedReader();

String temp = null;

while((temp=br.readLine()) != null){
syso(temp); // print 输出一行 ,不带换行符
}

br.close();

接收键盘输入

Scanner s = new Scanner(System.in); //标准输入流,接收键盘输入

// 程序停在此处,等待用户输入
String str = s.next();

syso(str);


输入 hello world 输出 hello , 以空格为分割



BufferedReader 接收用户输入

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String str = br.readLine();

syso(str);

br.close();


BufferedWriter

//BufferedWriter bw = new BufferedWriter(new FileWriter("temp04"));


BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("temp04",true)));
bw.write("欧云华");

//写入一个行分割符
bw.newLine();

bw.write("sssssssssssss");


bw.flush();



复制:BufferedReader BufferedWriter

BufferedReader br = new BufferedReader(new FileReader("temp04"));

BufferedWriter bw = new BufferedWriter(new FileWriter("C:/temp");

String temp = null;

while((temp=br.readLine()) !=null){
bw.write(temp);
bw.newLine();
}

bw.flush();
br.close();

bw.close();