java学习笔记--文件传输io流

1、java.io.File类用于表示文件(目录),File类只用于表示文件(目录)的信息(名称、大小),不能用于文件内容的访问
package com.imooc.file;

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

public class FileDemo {

public static void main(String[] args){
    //创建一个目录对象(路径使用双反斜杠,因为是转义字符)
    File file = new File("e:\\java\\imooc");
    //使用file.separator分隔符,任何操作系统都认识
    File file2 = new File("e:"+File.separator+"java"+File.separator+"imooc"+File.separator+"imooc2");
    System.out.println(file2.exists());
    if(!file2.exists()){
        //file2.mkdir();//只能创建单级目录
        file2.mkdirs();//创建多级目录
    }

    System.out.println(file2);
    //判断是否是一个目录
    System.out.println(file.isDirectory());
    //是否是一个文件
    System.out.println(file.isFile());

    //创建文件
    //File file3 = new File("e:\\java\\日记1.txt");
    //另一种构建方法
    File file3 = new File("e:\\java","日记1.txt");
    if(!file3.exists()){
        try {
            file3.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }else {
        file3.delete();//删除目录
    }

    //常用的File对象的api
    System.out.println(file3.toString());//文件的路径
    System.out.println(file3);//file.toString()的内容文件的路径
    System.out.println(file3.getAbsolutePath());//文件的路径
    System.out.println(file3.getName());//文件的名字
    System.out.println(file3.getParent());//父目录的名字



}

}
2、遍历目录list方法

package com.imooc.file;

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

import javax.lang.model.element.Element;

/**
 * 列出File的一些常用操作比如过滤、遍历操作
 * @author Administrator
 *
 */
public class FileUtils {

    public static void main(String[] args) throws IOException{
        FileUtils.listDirectory(new File("e:\\java"));


    }


    /**
     * 列出指定目录下(包括其子目录)的所有文件
     */
    public static void listDirectory(File dir)throws IOException{
        if(!dir.exists()){
            throw new IllegalArgumentException("目录:"+dir+"不存在");
        }
        if(!dir.isDirectory()){
            throw new IllegalArgumentException(dir+"不是目录 ");
        }

        /*String[] filenamesStrings = dir.list();//返回的是字符串数组,直接子的名称 不包含子目录下的内容
        for (String string : filenamesStrings) {
            System.out.println(dir+"\\"+string);
        }*/

        //如果要遍历子目录下的内容 就需要构造成File对象做递归操作,File提供了直接返回File对象的api
        File[] files = dir.listFiles();//返回的是直接子目录(文件)的抽象
        if(files!=null&&files.length>0){
            for (File file : files) {
                if(file.isDirectory()){
                    //递归
                    listDirectory(file);
                }else {
                    System.out.println(file);
                }
            }
        }
    }
}

3、RandomAccessFile
(1)java提供的对文件内容的访问,既可以读文件,也可以写文件且支(2)持随机访问文件,即可以访问文件的任意位置
(3)java文件模型:在硬盘中是byte byte byte 存储的,是数据的集合
(4) 打开文件:有两种模式“rw”(读写)、“r”(只读)
RandomAccessFile raf = new RandomAccessFile(file,”rw”)
文件指针,打开文件时指针在开头pointer =0;
(5)写方法
int b = raf.write(int);—–只写一个字节(后8位),同时指针指向下一个位置,准备再次写入
(6)读方法
int b = raf.read()—读一个字节
(7)文件读写完成以后一定要关闭(oracle官方说明若不关会有意想不到的错误d)

4、IO流(输入流、输出流)
字节流、字符流
1、字节流
1)InputStream:抽象了应用程序读取数据的方式
OutputStream:抽象了应用程序写出数据的方式
2)EOF=End或读到-1,就是结尾
3)输入流的基本方法
int b = in.read();//读取一个字节无符号填充到int的第八位。-1是EOF
in.read(byte[] buf)//读取数据填充到字节数组buf
in.read(byte[] buf,int start,int size)//读取数据到字节数组buf,从start开始长度为size
4)输出流的基本方法
out.write(int b)//写一个byte到流,b的低八位,int是32为
out.write(byte[] buf)将buf 字节数组都写入到流
out.write(byte[] buf,int start,int size
5)子类FileInputStream—-具体实现了在文件上读取数据

package com.imooc.file;

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

public class IOUtil {

    public static void main(String[] args) {

        /*try {
            IOUtil.printHex("e:\\java\\HelloWorld.class");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/

        try {
            IOUtil.printHexByByte("e:\\java\\HelloWorld.class");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     *read()方法读取单个字节
     *读取指定文件的内容,按照16进制 输出到控制台
     *并且每输出10个byte换行
     * @throws FileNotFoundException 
     */
    public static void printHex(String fileName) throws IOException{
        //把文件作为字节流进行读操作
        FileInputStream in = new FileInputStream(fileName);
        int b;
        int i = 1;
        while ((b=in.read())!=-1) {
            if(b<=0xf){
                System.out.print("0");
            }
            System.out.print(Integer.toHexString(b)+"  ");
            if(i++%10==0){
                System.out.println();
            }
        }
        in.close();
    }


    /**
     * 带参数的read()方法可以一次读取多个字节
     * 从in中读取字节到数组buf中
     * 从第零个开始最多读buf.length个
     * 返回的是读到的字节的个数
     */
    public static void printHexByByte(String fileName) throws IOException{
        FileInputStream in = new FileInputStream(fileName);
        byte[] buf = new byte[20*1024];//20k

        /*int bytes = in.read(buf,0,buf.length);
        int j = 1;
        for(int i=0;i<bytes;i++){
            if(buf[i]<=0xf){
                System.out.println("0");
            }
            System.out.print(Integer.toHexString(buf[i])+"  ");
            if(j++%10==0){
                System.out.println();
            }
        }*/

        /**
         * 当buf不够大时,用while循环控制当buf读满时重新再读
         * byte类型为8为,int类型为32位为了避免数据转换类型错误,
         * 通过0xff将高24为清零    ,当buf足够大时则不用清零,因为数组buf默认初始化为0                                                                    
         */
        int bytes = 0;
        int j = 1;
        while((bytes = in.read(buf,0,buf.length))!=-1){
            for(int i=0;i<bytes;i++){
                System.out.print(Integer.toHexString(buf[i]&0xff)+"  ");

                if(j++%10==0){
                    System.out.println();
                }
            }
        }
    }

}

6)子类FileOutputStream—-具体实现了在文件上读取数据

package com.imooc.file;

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

public class FileOutputDemo {

    public static void main(String[] args) throws IOException {

        //当文件不存在时,直接创建文件,如果存在,删除后创建
        FileOutputStream out = new FileOutputStream("demo/out.dat");

        //当文件存在时,会往文件后面追加内容
        //FileOutputStream out = new FileOutputStream("demo/out.dat",true);
        out.write('A');//写入低八位
        out.write('B');//write只能写如八位,所以要写四次
        int a = 10;
        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("demo/out.dat");//双斜杠单斜杠都可以



    }

7)实现文件的拷贝功能

public static void copyFile(File srcFile, File desFile) throws IOException {
        if (!srcFile.exists()) {
            throw new IllegalArgumentException("文件:" + srcFile + "不存在!");

        }
        if (!srcFile.isFile()) {
            throw new IllegalArgumentException(srcFile + "不是文件!");
        }

        FileInputStream in = new FileInputStream(srcFile);
        FileOutputStream out = new FileOutputStream(desFile);

        byte[] buf = new byte[8 * 1024];
        int b;
        while ((b = in.read(buf, 0, buf.length)) != -1) {
            out.write(buf, 0, b);
            out.flush();// 最好加上
        }
        in.close();
        out.close();

    }

8)DataOutputStream和DataInputStream
对流功能的扩展,可以更加方便的读取intlong字符等类型数据
DataOutputStream中增加方法
writeInt()和writeDouble()和writeUTF()等方法

1、package com.imooc.file;

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

public class DosDemo {

public static void main(String[] args) throws IOException {
    String file="e:\\java\\3.txt";
 //新建dataoutputstream流将数据写入基础fileoutputstream流
    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);


}

}


2、

package com.imooc.file;

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

public class DisDemo {

public static void main(String[] args)throws IOException {
    String file = "e:\\java\\3.txt";
    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);
    char c = dis.readChar();
    System.out.println(c);
    char c2 = dis.readChar();
    System.out.println(c2);
    dis.close();

}

}

8)字节缓冲流
BufferedInputStream和BufferedOutputStream:读写文件时会加缓冲区提高性能
加入从应用程序中把输入放入文件,相当于将一缸水放入另一缸中
FileOuputStream---write()一滴一滴的转移
DataOutputStream----writeXxx():一瓢一瓢的转移
BufferedOutputStream----write方法:一瓢一瓢的放入桶中在放入缸中

9copy文件的三种方法

/**
* 文件的copy操作,批量拷贝(最快的)
*/

public static void copyFile(File srcFile, File desFile) throws IOException {
    if (!srcFile.exists()) {
        throw new IllegalArgumentException("文件:" + srcFile + "不存在!");

    }
    if (!srcFile.isFile()) {
        throw new IllegalArgumentException(srcFile + "不是文件!");
    }

    FileInputStream in = new FileInputStream(srcFile);
    FileOutputStream out = new FileOutputStream(desFile);

    byte[] buf = new byte[8 * 1024];
    int b;
    while ((b = in.read(buf, 0, buf.length)) != -1) {
        out.write(buf, 0, b);
        out.flush();// 最好加上
    }
    in.close();
    out.close();

}

/**
 * 利用带缓冲的流进行文件的copy操作,一个字节一个字节的读取(比不带缓冲的要快)
 */

public static void copyFileByBuffer(File srcFile,File desFile)throws IOException{
    if(!srcFile.exists()){
        throw new IllegalArgumentException("文件:"+srcFile+"不存在!");
    }
    if(!srcFile.isFile()){
        throw new IllegalArgumentException(srcFile+"不是一个文件");
    }
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desFile));
    int c;
    while((c=bis.read())!=-1){
        bos.write(c);
        bos.flush();//必须加上刷新缓冲区
    }
    bis.close();
    bos.close();
}

/**
 * 不带缓冲的一个字节一个字节的读
 */
public static void copyFileByByte(File srcFile,File desFile)throws IOException{
    if(!srcFile.exists()){
        throw new IllegalArgumentException("文件:"+srcFile+"不存在!");
    }
    if(!srcFile.isFile()){
        throw new IllegalArgumentException(srcFile+"不是一个文件");
    }
    FileInputStream fis = new FileInputStream(srcFile);
    FileOutputStream fos = new FileOutputStream(desFile);
    int c;
    while((c=fis.read())!=-1){
        fos.write(c);
        fos.flush();//可以不加,最好加上
    }

    fis.close();
    fos.close();
}

***5、字符流***
1)编码问题
一个项目有自己的编码类型,当将一个gbk编码的txt文件的文字复制到utf-8的文件中时文字变为utf-8编码,无乱码,当直接将一个gbk编码的文件复制到一个utf-8的项目下是会出现乱码
2)认识文本和文本文件
java的**文本**是16位无符号整数,是字符的unicode编码(双字节编码)
**文件**是byte byte byte ...的数据序列
**文本文件**是文本(char)序列按照某种编码方案(utf-8、utf-16be、gbk)序列化为byte 的存储的结果
3)字符流(Reader writer)
字符的处理,一次处理一个字符
字符的底层仍然是基本的字节序列
字符流的的基本实现:
InputStreamReader:完成byte流解析为char流,按照编码解析
OutputStreamWriter:提供char流到byte流,按照编package com.imooc.file;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class IsrAndOswDemo {

public static void main(String[] args)throws IOException {
FileInputStream in = new FileInputStream("e:\\java\\wenzi.txt");

InputStreamReader isr = new InputStreamReader(in);//默认项目的编码,当文件编码和项目编码不一致时,
//为实际项目编码
FileOutputStream out = new FileOutputStream("e:\\java\\wenzi2.txt");
OutputStreamWriter osw = new OutputStreamWriter(out);
/**
 * 单个字符读取
 */
int c;
while((c=isr.read())!=-1){
System.out.print(c);
}


/**
 * 批量读取,放入buffer数组中,从0开始,
 * c是返回的读到的字符的个数
 */
char[] buffer = new char[8*1024];
int c;
while((c=isr.read(buffer, 0, buffer.length))!=-1){
String s = new String(buffer,0,c);
System.out.println(s);
//写入文件wenzi2.txt
osw.write(buffer,0,c);
osw.flush();

}
isr.close();
osw.close();
}
}

4)字符流操作的单位是字符,需要考虑编码问题,字节流操作的单位是字节,不用考虑编码问题

5)FileReader和FileWriter

/**
* 使用FileReader和FileWriter类可以直接操作文件(文件对象或文件路径)
*/

    FileReader fr = new FileReader("e:\\java\\wenzi.txt");//当此处出   //现编码问题是就要使用InputStreamReader类了
    FileWriter fw = new FileWriter("e:\\java\\wenzi3.txt");//当加上//true参数时,不会把已经存在的文件删除,而是在文件后面追加内容

    char[] buffer = new char[8*1024];
    int c;
    while((c=fr.read(buffer, 0, buffer.length))!=-1){
        fw.write(buffer,0,c);
        fw.flush();
    }
    fr.close();
    fw.close();
6)字符流的过滤器
BufferedReader------->readLine一次读一行
BufferedWriter\printWriter-------->一次写一行

package com.imooc.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class BrAndBwDemo {

public static void main(String[] args) throws IOException{
    BufferedReader br = new BufferedReader
            (new InputStreamReader(new FileInputStream("e:\\java\\wenzi.txt")));

// BufferedWriter bw = new BufferedWriter
// (new OutputStreamWriter(new FileOutputStream(“e:\java\wenzi2.txt”)));

    PrintWriter pw = new PrintWriter("e:\\java\\wenzi3.txt");
    //PrintWriter pw = new PrintWriter(outputStream,boolean autoFlush);自动刷新

    String line;
    while((line = br.readLine())!=null){
        System.out.print(line);//一次读一行但是并不能识别换行,需单独添加换行语句,
                                 //这里是通过println换行的

// bw.write(line);//写入到文件wenzi2.txt
// bw.newLine();//换行
// bw.flush();//必须刷新缓冲区

        pw.println(line);
        pw.flush();

    }
    br.close();
    //bw.close();
    pw.close();
}

}


***6、序列化基本操作***
1)对象的序列化和反序列化:对象的序列化是将对象转换成byte序列,反之叫对象的反序列化
2)序列化流(ObjectOutputStream),是过滤流-----方法:writeObject
反序列流(ObjectInputStream),-------方法readObject
3)序列化接口(Serializable)
对象必须实现序列化接口 ,才能进行序列化,否则将出现异常,这个接口没有任何方法,只是一个标准
4)路径的斜杠问题:正斜杠通用字符串中可用单斜杠,反斜杠在字符串中则要双写

package com.imooc.file;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ObjectSerialDemo {

public static void main(String[] args)throws Exception{
    String file = "demo/obj.dat";
    //1、对象的序列化注意student类要实现serializable接口
    /*ObjectOutputStream oos = 
            new ObjectOutputStream(new FileOutputStream(file));
    Student stu = new Student("10001","张三",20);
    oos.writeObject(stu);
    oos.flush();
    oos.close();*/

    //反序列化
    ObjectInputStream ois = new 
            ObjectInputStream(new FileInputStream(file));
    Student stu = (Student)ois.readObject();
    System.out.print(stu);
    ois.close();
}

}
“`

5)当给student类的某个属性加上transient关键字时该属性不会进行jvm默认的序列化,也可以自己完成这个元素的序列化

需要给student类加上一下两个方法,以便自己完成某些元素的序列化
//序列化
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{}
//反序列化
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException,ClassNotFoundException{}
分析ArrayList源码中序列化和反序列化的问题

5)序列化中子类和父类构造函数的调用问题
当对子类进行序列化时,如果其父类没有实现序列化接口,那么其父类的构造函数会被调用,否则不被调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值