文件传输基础——Java IO流

了解

  1. 文件的编码
  • File类的使用
  • RandomAccessFile类的使用
  • 字节流
  • 字符流
  • 对象的序列化和反序列化

文件的编码

有时候我们打开一个文件或者是网页发现里面出现的都是乱码。其原因是编辑文件时所采用的编码方法和打开文件时所采用的解码方式不同,所以造成打开文件看到的都是乱码。
在Java中,GBK编码中文占用2个字节,英文占用1个字节,UTF-8编码中,中文占用3个字节,英文占用1个字节。
范例

import java.io.UnsupportedEncodingException;

/**
 * Created by 99479 on 2017/7/11.
 */
public class EncodeDemo01 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        String s = "蒲杰ABC";
        byte [] bytes = s.getBytes("gbk");//转换成字节序列,用的是项目默认的编码
        for (byte b:
             bytes) {
            //把字节(转换了int)以16进制的方式显示
            System.out.print (Integer.toHexString(b & 0xff)+"   ");
        }
        System.out.println();
        for (byte b:
             s.getBytes("utf-8")) {
            System.out.print(Integer.toHexString(b & 0xff)+"  ");
        }
        System.out.println();
        /**
         * 当你的字节序列是某种编码时,这个时候想把字节序列变成字符串,也需要用这种编码方式,否者会出现乱码
         */
        String s1 = new String(bytes);//用项目的默认编码
        System.out.println(s1); //输出乱码
        String s2 = new String(bytes,"gbk");
        System.out.println(s2);
        /**
         * 文本文件 就是字节序列
         * 可以是任意编码的字节序列
         * 入股我们在中文机器机器上直接创建文本文件,那么该文本文件只认识snsi编码
         */
    }
}

输出

c6   d1   bd   dc   41   42   43   
e8  92  b2  e6  9d  b0  41  42  43  
�ѽ�ABC
蒲杰ABC

File类的使用##

在Java中,File类用于表示文件或者表示目录。在java.io.File包中。File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问。下面的范例都演示File类的基本操作。
范例1,常用API

import java.io.File;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/11.
 */
public class FileDemo {
    public static void main(String[] args) {
        //了解构造函数
        File file = new File("d:"+File.separator+"javaio");
        //查看文件是否存在
        System.out.println(file.getName()+"     是否存在:" +file.exists());
        //如果不存在就创建此文件夹,存在就删除此文件
        if(!file.exists()){
            file.mkdir();//创建文件夹
            //判断是否时一个目录
            System.out.println(file.getName()+"     是否是一个文件夹:" + file.isDirectory());
            //判断是否时一个文件
            System.out.println(file.getName()+"     是否是一个文件:" + file.isFile());
        }else {
            boolean isDelete = file.delete();
            System.out.println(file.getName()+"     是否删除成功:" + isDelete);
        }


        //创建一个文件对象
        File file1 = new File("d:"+File.separator+"日记.txt");
        System.out.println(file1.getName() + "      文件是否存在:" + file1.exists());
        if (!file1.exists()){
            try {
                boolean isCreat = file1.createNewFile();
                System.out.println(file1.getName()+"    是否创建成功:"+ isCreat);
                System.out.println(file1.getName()+"    是否是一个文件夹:" + file1.isDirectory());
                System.out.println(file1.getName()+"    是否是一个文件:" + file.isFile());
                System.out.println(file1.getName()+"    的绝对路径:" + file1.getAbsolutePath());
                System.out.println(file1.getName()+"    的父路径:" + file1.getParent());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else {
            boolean isDelete = file1.delete();
            System.out.println(file1.getName()+"    是否删除成功:"+ isDelete);
        }
    }

}

输出

javaio     是否存在:true
javaio     是否删除成功:true
日记.txt      文件是否存在:false
日记.txt    是否创建成功:true
日记.txt    是否是一个文件夹:false
日记.txt    是否是一个文件:false
日记.txt    的绝对路径:d:\日记.txt
日记.txt    的父路径:d:\

范例2,遍历目录
FileUtil.java

import java.io.File;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/12.
 * 列出File的一些常用操作比如过滤、遍历等操作
 */
public class FileUtils {
    /**
     *  列出某个目录的所有文件或者包括子目录中的所有文件和文件夹
     * @param dir
     * @throws IOException
     */
    public static void listDirectory(File dir) throws IOException{
        if (!dir.exists()){
            throw new IllegalArgumentException("目录:"+dir+"不存在");
        }
        if (!dir.isDirectory()){
            throw new IllegalArgumentException(dir+"不是目录");
        }
        String [] filenames = dir.list();
        File[] files = dir.listFiles();
        for (File file: files) {
            if (file.isFile()){
                System.out.println("文件: "+file.getAbsolutePath());
            }else if (file.isDirectory()){
                System.out.println("文件夹:"+file.getAbsolutePath());
                //递归调用
                listDirectory(file);
            }

        }
    }
}

FileUtilTest01.java

import java.io.File;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/12.
 */
public class FileUtilsTest01 {
    public static void main(String[] args) {
        try {
            FileUtils.listDirectory(new File("D:"+File.separator+"迅雷下载"+File.separator+"杀不死"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出

文件夹:D:\迅雷下载\杀不死\test
文件: D:\迅雷下载\杀不死\test\0.0.txt
文件夹:D:\迅雷下载\杀不死\test\新建文件夹
文件: D:\迅雷下载\杀不死\test\新建文件夹\tstsbg.txt
文件: D:\迅雷下载\杀不死\[杀BS]第01集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第02集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第03集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第04集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第05集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第06集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第07集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第08集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第09集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第10集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第11集_bd.mp4
文件: D:\迅雷下载\杀不死\[杀BS]第12集_bd.mp4

RandomAccessFile基本操作

RandomAccessFile时Java提供的对文件内容的访问类,既可以读文件,也可以写文件。RandomAccessFile支持随机访问文件,可以访问文件的任意位置
(1)Java的文件模型
在硬盘上的文件是以byte byte byte存储的,时数据的集合。
(2)打开文件有两种模式
1、“rw”读写。2、“r”只读。
在使用RandomAccessFile操作文件的时候不仅要传入要操作文件的路径,还要传入操作文件的方式,例:RandomAccessFile raf = new RandomAccessFile("file","rw");
由于是随机访问文件,它包含一个文件指针,打开文件时指针在开头 pointer = 0;
(3)、写方法
raf.write(int) ---> 只写一个字节(后8位),同时指针指向下一个位置,准备再次写入。
(4)、读方法
int b = raf.read() ---> 读一个字节
(5)、文件读写完成后一定要关闭(Oracle官方说明),以防出现意想不到的错误。
范例

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;

/**
 * Created by 99479 on 2017/7/12.
 */
public class RafDemo {
    public static void main(String[] args) throws IOException {
        File demo = new File("demo");
        if (!demo.exists()){
            demo.mkdir();
        }
        //以demo为父目录
        File file = new File(demo,"raf.dat");
        if (!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println(file.getAbsolutePath());

        RandomAccessFile raf = new RandomAccessFile(file,"rw");
        //指针的位置
        System.out.println("指针的位置"+raf.getFilePointer());

        System.out.println("开始写文件...");
        raf.write('A');//只写了一个字节
        System.out.println("指针的位置"+raf.getFilePointer());
        raf.write('B');

        int i=0x7fffffff;
        //用write方法每次只写一个字节,如果要把i写进去就得写4次
        raf.write(i>>>24);//高八位
        raf.write(i>>>16);
        raf.write(i>>>8);
        raf.write(i);
        System.out.println("指针的位置"+raf.getFilePointer());

        //可以直接写一个int
        raf.writeInt(i);

        //写一个中文字符(先转换成字节)
        String s = "中";
        byte [] gbk = s.getBytes("gbk");
        raf.write(gbk);

        System.out.println("文件的长度: "+raf.length());

        System.out.println("开始读文件...");
        //读文件,必须把指针移到头部
        raf.seek(0);
        //一次性读取,把文件中的内容都读到字节数组中
        byte [] buf = new byte[(int)(raf.length())];
        raf.read(buf);
        System.out.println(Arrays.toString(buf));
        
        //关闭文件操作流
        raf.close();
    }
}

输出

D:\IdeaProjects\TestDemo\demo\raf.dat
指针的位置0
开始写文件...
指针的位置1
指针的位置6
文件的长度: 12
开始读文件...
[65, 66, 127, -1, -1, -1, 127, -1, -1, -1, -42, -48]

首先要了解流的概念,在Java中IO流就是输入输出流,在这里面也分为了字节流、字符流

字节流##

(1)字节流又分为InputStream、OutputStream两个抽象类
InputStream:抽象了应用程序读取数据的方式。
OutputStream:抽象了应用程序写出数据的方式。

(2)读到返回值为-1就表示已经读到结尾。

(3)字节输入流基本方法:

  • int b = in.read();读取一个字节无符号填充到int低八位。读到-1结束
  • in.read(byte [] buf)读取数据填充到字节数组
  • in.read(byte [] buf,int start,int size)读取数据填充到字节数组buf,从buf的start位置开始存放size长度的数据。

(4)字节输出流的基本方法:

  • out.write(int b)写出一个byte到流,b的低八位
  • out.write(byte [] buf)将buf字节数据都写入到流
  • out.write(byte [] buf,int start,int size)字节数组buf从start位置开始写size长度的字节流。
    了解
  1. 字节流之文件输入流FileInputStream
  • 字节流之文件输出流FileOutputStream
  • 字节流之数据输入输出流
  • 字节缓冲流

字节流之文件输入流FileInputStream

FileInputStream继承了抽象类InputStream。具体实现了在文件上读取数据。
范例
IOUtil

import java.io.FileInputStream;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/13.
 */
public class IOUtil {
    /**
     * 读取指定文件内容,按照16进制输出到控制台
     * 并且每输出10个byte就换行
     * @param fileName
     */
    public static void printHex(String fileName) throws IOException{
        //把文件作为字节流进行读操作
        FileInputStream in = new FileInputStream(fileName);
        int b;
        int i = 1;
        while((b = in.read()) != -1){
            System.out.print(Integer.toHexString(b)+"  ");
            if (i++%10 == 0){
                System.out.println();
            }
        }
        //关闭输入流
        in.close();
    }

    public static void printHexByByteArray(String fileName)throws IOException{
        FileInputStream in = new FileInputStream(fileName);
        byte [] buf = new byte[20*1024];
        //从in中批量读取字节,放入到buf这个字节数组中,
        // 从第0个位置开始放,最多放buf.length个,
        //返回的是读到的字节的个数
        int bytes = in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大
        int j = 1;
        for (int i = 0 ; i < bytes ; i++){
            if (buf[i] <= 0xf){
                System.out.print("0");
            }
            System.out.print(Integer.toHexString(buf[i])+"  ");
            if (j++%10 == 0){
                System.out.println();
            }
        }

    }

}

IOUtilTest01

import java.io.IOException;

/**
 * Created by 99479 on 2017/7/13.
 */
public class IOUtilTest01 {
    public static void main(String[] args) {
        try {
            IOUtil.printHex("D:\\IdeaProjects\\TestDemo\\demo\\raf.dat");

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

IOUtilTest02

import java.io.IOException;

/**
 * Created by 99479 on 2017/7/13.
 */
public class IOUtilTest02 {
    public static void main(String[] args) {
        try {
            IOUtil.printHexByByteArray("D:\\IdeaProjects\\TestDemo\\demo\\raf.dat");

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

字节流之文件输出流FileOutputStream

FileOutputStream实现了向文件中写出byte数据的方法,继承了OutputStream。
范例

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/13.
 */
public class FileOutDemo01 {
    public static void main(String[] args) throws IOException {
        //如果文件不存在,则直接创建,如果存在,删除后创建
        FileOutputStream out = new FileOutputStream("D:\\IdeaProjects\\TestDemo\\demo\\raf.dat");
        //如果是追加内容,则使用
//        FileOutputStream out = new FileOutputStream("D:\\IdeaProjects\\TestDemo\\demo\\raf.dat",true);
        out.write('A');//写出了A的低八位
        out.write('B');//写出了'B'的低八位
        int a = 10;//write只能写八位,那么写一个int需要写4次每次8位
        out.write(a >>> 24);
        out.write(a >>> 16);
        out.write(a >>> 8);
        out.write(a);
        byte[] gbk = "中国".getBytes("gbk");
        out.write(gbk);
        out.close();

        IOUtil.printHex("D:\\IdeaProjects\\TestDemo\\demo\\raf.dat");
    }
}

输出

41  42  0  0  0  a  d6  d0  b9  fa  

范例:利用文件输入流、文件输出流实现文件的拷贝
IOUtil

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/13.
 */
public class IOUtil {
    /**
     * 读取指定文件内容,按照16进制输出到控制台
     * 并且每输出10个byte就换行
     * @param fileName
     */
    public static void printHex(String fileName) throws IOException{
        //把文件作为字节流进行读操作
        FileInputStream in = new FileInputStream(fileName);
        int b;
        int i = 1;
        while((b = in.read()) != -1){
            System.out.print(Integer.toHexString(b)+"  ");
            if (i++%10 == 0){
                System.out.println();
            }
        }
        //关闭输入流
        in.close();
    }

    public static void printHexByByteArray(String fileName)throws IOException{
        FileInputStream in = new FileInputStream(fileName);
        byte [] buf = new byte[20*1024];
        //从in中批量读取字节,放入到buf这个字节数组中,
        // 从第0个位置开始放,最多放buf.length个,
        //返回的是读到的字节的个数
        int bytes = in.read(buf,0,buf.length);//一次性读完,说明字节数组足够大
        int j = 1;
        for (int i = 0 ; i < bytes ; i++){
            if (buf[i] <= 0xf){
                System.out.print("0");
            }
            System.out.print(Integer.toHexString(buf[i])+"  ");
            if (j++%10 == 0){
                System.out.println();
            }
        }

    }

    public static void copyFile(File srcFile,File desFile) throws IOException{
        if (!srcFile.exists()){
            throw new IllegalArgumentException("文件不存在");
        }
        if (!srcFile.isFile()){
            throw new IllegalArgumentException(srcFile+"不是文件");
        }
        FileInputStream in = new FileInputStream(srcFile);//读操作
        FileOutputStream out = new FileOutputStream(desFile);//写操作
        byte [] buf = new byte[8];
        int b = 0 ;
        while(b != -1){
            b =  in.read(buf,0,buf.length);
            System.out.print(b+"      ");
            out.write(buf,0,buf.length);
            out.flush();//最好加上
        }
        in.close();
        out.close();

    }

}

IOUtilTest03

import java.io.File;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/13.
 */
public class IOUtilTest03 {
    public static void main(String[] args) {
        try {
            IOUtil.copyFile(new File("D:\\IdeaProjects\\TestDemo\\demo\\raf.dat"),new File("D:\\IdeaProjects\\TestDemo\\demo\\NEWraf.txt"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出

8      8      8      8      8      8      8      8      8      8      8      8      8      8      8      8      8      8      3      -1      
拷贝结果

字节流之数据输入输出流DataOutputString/DataInputStream

这一组操作类是对“流”的扩展,可以更加方便的读取int,long/字符等类型数据。
DataOutputString中的方法举例:writeInt() 、 writeDouble() 、writeUTF()

范例:DataOutputStream

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/19.
 * 往一个文件里面写数字,或者写普通的数据类型
 */
public class DosDemo {
    public static void main(String[] args) throws IOException{
        String file = "demo/dos.dat";
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));

        dos.writeInt(10);
        dos.writeInt(-10);
        dos.writeLong(10l);
        dos.writeDouble(10.5);
        //采用UTF-8编码写出
        dos.writeUTF("中国");
        //采用UTF-16BE编码写出
        dos.writeChars("中国");
        dos.close();
        IOUtil.printHex(file);
    }
}

输出

0  0  0  a  ff  ff  ff  f6  0  0  
0  0  0  0  0  a  40  25  0  0  
0  0  0  0  0  6  e4  b8  ad  e5  
9b  bd  4e  2d  56  fd  

范例:DataInputStream

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/19.
 */
public class DisDemo {
    public static void main(String[] args) throws IOException{
        String file = "demo/dos.dat";
        IOUtil.printHex(file);
        DataInputStream dis = new DataInputStream(new FileInputStream(file));
        int i = dis.readInt();
        System.out.println(i);
        i = dis.readInt();
        System.out.println(i);
        long l = dis.readLong();
        System.out.println(l);
        double d = dis.readDouble();
        System.out.println(d);
        String s = dis.readUTF();
        System.out.println(s);

        dis.close();
    }
}

输出

0  0  0  a  ff  ff  ff  f6  0  0  
0  0  0  0  0  a  40  25  0  0  
0  0  0  0  0  6  e4  b8  ad  e5  
9b  bd  4e  2d  56  fd  10
-10
10
10.5
中国

字节缓冲流

字节缓冲流主要学习了解BufferedInputStream和BuferedOutputStream
这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式主要提高了IO的输入输出性能。
从应用程序中把数据输入放入文件,相当于将一缸水倒入到另一个缸中,其中:
FileOutputStream ---> write()方法相当于一滴一滴地把水“转移”过去。
DataOutputStream ---> writeXxx()方法会方便一些,相当于一瓢一瓢的把水“转移”过去。
BufferedOutputStream ---> write()方法更方便,相当于一瓢一瓢先放入桶中,再从桶中倒入到另一个缸中,提高了性能。
范例:修改IOUtil.java
增加方法:copyFileByBuffer

    /**
     * 进行文件的拷贝,使用带缓冲的字节流
     * @param srcFile
     * @param destFile
     * @throws IOException
     */
    public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{
        if (!srcFile.exists()){
            throw new IllegalArgumentException("文件不存在");
        }
        if (!srcFile.isFile()){
            throw new IllegalArgumentException(srcFile+"不是文件");
        }
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        int c ;
        while((c = bis.read()) != -1){
            bos.write(c);
            bos.flush();//刷新缓冲区
        }
        bis.close();
        bos.close();
    }

范例:IOUtilTest04

import java.io.File;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/19.
 */
public class IOUtilTest04 {
    public static void main(String[] args) throws IOException {
        IOUtil.copyFileByBuffer(new File("D:\\test.txt"),new File("D:\\test\\new_test.txt"));
    }
}

输出
之前的:

test.txt

之后的:

new_test.txt

字符流

字符流操作文本文件,如果是MP3,图片,视频之类的文件都采用字节流。

字符流的基本概念:

  1. 编码问题
  • 认识文本和文本文件:Java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)。文件是byte byte byte...的序列,文本文件是文本(char)序列按照某种编码方案(utf-8、utf-16be、gbk)序列化为byte的存储结构。
  • 在Java里面的字符流也有读(Reader抽象类),写(Writer抽象类),字符的处理,一次处理一个字符,字符的底层仍然是基本的字节序列。
  • Java中字符流的基本条件:
    InputStreamReader 完成byte流解析为char流,按照编码解析。
    OutputStreamWriter 提供char流到byte流,按照编码处理。
    范例:对一个文件进行简单的读操作
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Created by 99479 on 2017/7/20.
 */
public class IsrAndAOswDemo {
    public static void main(String[] args) throws IOException{
        FileInputStream in = new FileInputStream("D:\\test.txt");
        InputStreamReader isr = new InputStreamReader(in,"utf-8");//项目的默认编码
//        int c ;
//        while((c = isr.read()) != -1){
//            System.out.print((char)c);
//        }
        char [] buffer = new char[8*1024];
        int c;
        //批量读取,放入buffer这个字符数组,从第0个位置开始方式,最多放buffrt.length个
        //返回的是读到的个数
        StringBuffer stringBuffer = new StringBuffer();
        while ((c = isr.read(buffer,0,buffer.length)) != -1){
            stringBuffer.append(buffer,0,buffer.length);
        }
        System.out.println(stringBuffer);

        isr.close();//一定要注意关闭,注意关闭,注意关闭
    }
}

输出

客家话和;oh;一; 可不行了就回北京了黑戈壁厉害个i好吧;;iuh
;和哦哦哦回家oh;和
字符流的基本概念:
1. 编码问题
- 认识文本和文本文

字符流的另一组操作类:
写文件:FileWriter
写文件:FileReader
刚刚做的字符流的读写操作类(InputStreamReader、OutputStreamReader)使用时嵌套了一个类,如果使用FileWriter、FileReader就很方便了。
范例:做读写操作

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Created by 99479 on 2017/7/20.
 */
public class FrAndFwDemo {
    public static void main(String[] args) throws IOException{
        FileReader fr = new FileReader("D:\\test.txt");
        FileWriter fw = new FileWriter("D:\\test\\new_test.txt");
        char [] buffer = new char[1024];
        int c;
        while((c = fr.read(buffer,0,buffer.length)) != -1){
            fw.write(buffer,0,buffer.length);
            fw.flush();
        }
        //注意关闭,注意关闭,注意关闭
        fr.close();
        fw.close();
    }
}

字符流的过滤器

我们可以对字符流加过滤器,让字符流有更多的功能,常用的有一组:
BufferedReader,它最强大的功能有一个是 ---> readLine 一次读一行。
BufferedWriter/PrintWriter: ---> 写一行。
范例:

import java.io.*;

/**
 * Created by 99479 on 2017/7/20.
 */
public class BrAndBwOrPwDemo {
    public static void main(String[] args) throws IOException{
        //对文件进行读写操作
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("D:\\test.txt")));
//        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\test\\new_test.txt")));
        PrintWriter pw = new PrintWriter("D:\\test\\new_test.txt");
        String line;
        while((line = br.readLine()) != null){//读一行
            System.out.println(line);//一次读一行,并不能识别换行
//            bw.write(line);
//            bw.newLine();//换行操作
//            bw.flush();

            pw.println(line);
            pw.flush();
        }
        br.close();
//        bw.close();

        pw.close();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352