Java-IO流

@Test
public void test() {
    ItemService is = new ItemService();
    is.readTestFile("src\\item.txt");
}

File类

1. File类的使用

  • File类的一个对象,代表一个文件或文件目录(俗称文件夹)
  • File类声明在java.io包中

1.1.创建file的实例

public class main {
    @Test
    public void test(){

        File file = new File("H:\\IO流测试\\hello.txt");//绝对路径
        File file2 = new File("hello.txt");//相对路径

    }
}
  • 相对路径:相较于某个路径下,指明的路径。
  • 绝对路径:包含盘符在内的文件或文件目录的路径。

1.2.路径分隔符

  • 路径中的每级目录之间用一个路径分隔符来隔开
    • windows和DOS系统默认使用\来表示(java避免表示的是转义,使用2个\),Unix和URL使用/来表示。
  • java程序支持跨平台运行,因此路径分隔符要慎用。
    • 为了解决这个隐患,File类提供了一个常量
    • public static final String separator,根据操作系统,动态德提供分隔符。

1.3.File类的构造器

1.3-1构造器一:路径

File(String pathname):路径

File file = new File("H:\\IO流测试\\hello.txt");
System.out.println(file);
//输出结果
H:\IO流测试\hello.txt
 File file = new File("H:\\IO流测试\\hello.txt");
        File file2 = new File("hello.txt");
		System.out.println(file2);
//输出结果
hello.txt
1.3-2构造器二:目录

File(String parentPath,String childPath)

前面是父目录,后面是一个子目录。

File file3 = new File("H:\\\\IO流测试\\\\hello.txt\"","javaSenior");
System.out.println(file3);
//输出结果
H:\IO流测试\hello.txt"\javaSenior

构造器三:File+目录

 File file3 = new File("H:\\\\IO流测试\\\\hello.txt\"","javaSenior");
        File file4 = new File(file3,"hello.txt");
        System.out.println(file4);
//输出结果
H:\IO流测试\hello.txt"\javaSenior\hello.txt

2.File类的方法

2.1.检查方法

  • public boolean isDirectory():判断是否是文件目录
  • public boolean isFile():判断时否是文件
  • public boolean exists():判断时否存在
  • public boolean canRead():判断是否可读
  • public boolean canWrite:判断是否可写
  • public boolean isHidden():判断是否隐藏

在该盘符下创建hello.txt的前提下

@Test
    public void test(){
        File file = new File("H:\\IO流测试\\hello.txt");
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.exists());
        System.out.println(file.canRead());
        System.out.println(file.canWrite());
        System.out.println(file.isHidden());

    }
//输出结果
false//不是目录
true//是一个文件
true//存在该文件
true//可读,因为没有对文件进行不可读修改
true//可写
false//没有隐藏
    
    //如果没有创建hello.txt则全部都是false
@Test
    public void test(){
        File file = new File("H:\\IO流测试");
        System.out.println(file.isDirectory());
        System.out.println(file.isFile());
        System.out.println(file.exists());
        System.out.println(file.canRead());
        System.out.println(file.canWrite());
        System.out.println(file.isHidden());

    }
//输出结果
true//是一个目录
false
true
true
true
false

2.2 创建的方法

  • public boolean createNewFile():创建目录,如果文件存在则不创建,返回false。
  • public boolean mkdir():创建文件目录。如果此文件目录存在就不创建。
  • public boolean mkdirs():创建文件目录。如果上层文件不存在,一并创建。
  • public boolean delete():删除文件或者文件夹。(删除不走回收站)
@Test
    public void test() throws IOException {
        File file = new File("H:\\IO流测试\\hello1.txt");
        file.createNewFile();//创建
        file.delete();//删除
    }

IO流

I表示input,o表示output。以前的程序数据都是存储在内存上面的,关机之后就不存在了,现在引入IO流,可以把数据存储在硬盘等,让数据持久化。

1.IO流的原理

I/O是Input/Output的缩写,I/O技术是非常使用的技术,可用于*处理设备设备之间的数据传输*。如读/写文件,网络通讯等。

  • 输入Input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
  • 输出Output:将程序(内存)数据输出到磁盘、光盘等存储设备中。

2 流的分类

  • 按数据单位分类
    • 字节流 8bit、字符流 16bit
  • 按流向不同分类
    • 输出流、输入流
  • 按流的角色分类
    • 节点流、处理流
抽象基类字节流字符流
输入流InputStreamReader
输出流OutpoutStramWriter
抽象基类节点流(文件流)缓冲流(处理流的一种)
InputStreamFileInputStreamBufferedInputSteam
OutputStreamFileOutputStreamBufferedOutputStream
ReaderFileReaderBufferedReader
WriderFileWriterBufferedWriter

3.流的使用

在流的使用最后一定要提供close方法来关闭流,否则会造成内存的泄露。

3.1 FileReader

public class main {
    public static void main(String[] args){
            FileReader fr =null;
        try {
            File file = new File("src\\hello.txt");
            fr = new FileReader(file);
            int data = fr.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fr.read();
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(fr != null){
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


  • 推荐使用的含参构造器写法

    //hello.txt内的字符
    helloworld123
    
    
    public class main {
        public static void main(String[] args) {
            FileReader fr = null;
            try {
                File file = new File("src\\hello.txt");
                fr = new FileReader(file);
                char[] cbuf = new char[5];
                int len;
                
                
    //            
                while ((len = fr.read(cbuf)) != -1) {
                    for (int i = 0; i < cbuf.length; i++) {
                        System.out.print(cbuf[i]);
                    }
                }
    //            
                
                
                
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (fr != null) {
                    try {
                        fr.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    
    }
    
    

    在//之间的for遍历要采用这种方法,而不能用cbuf.length,因为helloworld123有2组5个字符,1组三个字符,在第2组5个字符完成以后,在用后3个来覆盖前5个字符的时候,ld无法被覆盖掉,所以仍然会输出一个helloworld123ld,如果采用声明的len来确定需要的长度,则会正确输出helloworld123

3.2 FileWriter

执行以下操作之后,在src目录下的hello.txt内部就会写上2行i have a dream字符串。(并且每次运行时,是把之前的字符串覆盖,而不是往后面添加) 如果文件不存在,会在输出的时候自动创建。

public class FileWriterTest {
    @Test
    public void testFileWriter() throws IOException {
        //提供File类的对象,指明写出到的文件
        File file = new File("src\\hello.txt");

        //提供FileWriter的对象, 用于数据的写出
       

        //写出的操作
        wr.write("i have a dream!\n");
        wr.write("i have a dream!\n");

        //流资源的关闭
        wr.close();

    }
}

FileWriter另外一个构造器

 FileWriter wr = new FileWriter(file);
 如果将这个构造器改为如下
  FileWriter wr = new FileWriter(file,true);
  则表示在原有的文件之后添加内容。如果写false则会覆盖原有文件。

3.3 将一个文本文件的内容写到另外一个

public class testFileReaderAndWriter {
    public static void main(String[] args) {
            FileReader fr = null;
            FileWriter fw = null;
        try {
            File srcFile = new File("src\\hello.txt");
            File destFile = new File("src\\hello2.txt");

            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);

            char[] cbuf = new char[5];
            int len;
            while((len = fr.read(cbuf)) != -1){

                    fw.write(cbuf[i]);

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

3.4 将一个非文本文件复制到另外一个


public class FileInputOutputStreamTest {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File file = new File("src\\10.jpg");
            fis = new FileInputStream(file);
            fos = new FileOutputStream("11.jpg",false);
            byte[] buffer = new byte[5];
            int len;
            while((len = fis.read(buffer)) != -1){
  
                    fos.write(buffer,0,len);

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

    }

}
//实现结果,将10.jpg中的图片复制到了11.jpg中

3.5 编写复制的方法

  • 形参为srcPath(原文件路径)和destPath(复制到的文件路径)
public void copyFile(String srcPath,String destPath){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File srcFile = new File(srcPath);
            File destFile = new File(destPath);
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile,false);
            byte[] buffer = new byte[5];
            int len;
            while((len = fis.read(buffer)) != -1){

                    fos.write(buffer,0,len);

               
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fis != null && fos !=null){
                try {
					fos.close()
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

3.6 总结

  • 对于文本文件(.txt,.java,.c,.cpp),使用字符流处理
  • 对于非文本文件(.jpg,.mp3,.mp4,.doc,.ppt····),使用字节流处理

4.处理流之一:缓冲流

开发中,为了效率通常不适用节点流,而是使用缓冲流

处理流:“套接”在已有流的基础上。

4.1 缓冲流的使用

说明:在关闭流的时候只需要关闭外部流(缓冲流),内部流就可以自动关闭。


        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //造文件
            File srcFile = new File("src\\10.jpg");
            File destFile = new File("src\\12.jpg");
            //造流
            FileInputStream fis = new FileInputStream(srcFile);
            FileOutputStream fos = new FileOutputStream(destFile, false);
            //造缓冲流
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);
            //复制的细节:读取和写入
            byte[] buffer = new byte[10];
            int len;
            while ((len = bis.read(buffer)) != -1) {

                bos.write(buffer);

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

4.2 缓冲流的作用

  • 提高流的读取、写入的速度

  • flush()的作用是清除缓冲区。

4.3实现文本文件的复制

  • 方式一:使用char[]数组
public class testBufferedReaderBufferedWriter {
    @Test
    public void test(){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(new File("src\\hello.txt")));
            bw = new BufferedWriter(new FileWriter(new File("src\\hello2.txt")));
            char[] cbuf = new char[1024];
            int len;
            while((len = br.read(cbuf)) != -1){

                bw.write(cbuf,0,len);
	
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//执行结果:将hello.txt中的内容复制到了hello2.txt中
  • 方式二:使用String

4.4 实现图片的加密

public class 实现图片加密 {
    public static void main(String[] args) {
        BufferedInputStream br = null;
        BufferedOutputStream bw = null;
        try {
            br = new BufferedInputStream(new FileInputStream("src\\10.jpg"));
            bw = new BufferedOutputStream(new FileOutputStream("src\\10secret.jpg"));
            byte[] buffer = new byte[20];
            int len;
            while ((len = br.read(buffer)) != -1){
                for(int i =0;i<len;i++){
                    buffer[i] =(byte)(buffer[i]^5);
                }
                bw.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


}

4.5 实现图片的解密

public class 对已知加密文件的解密 {
    public static void main(String[] args) {
        BufferedInputStream br = null;
        BufferedOutputStream bw = null;
        try {
            br = new BufferedInputStream(new FileInputStream("src\\10secret.jpg"));
            bw = new BufferedOutputStream(new FileOutputStream("src\\10out.jpg"));
            byte[] buffer = new byte[20];
            int len;
            while ((len = br.read(buffer)) != -1){
                for(int i =0;i<len;i++){
                    buffer[i] =(byte)(buffer[i]^5);
                }
                bw.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if(bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


}

^为异或运算符,解密思路为:M对N进行2次异或运算就会变成M。

5.转换流

5.1 转换流:属于字符流

InputStreamReader(Reader下的):将一个字节的输入流转化为一个字符的输入流

OutputStreamWriter(Writer下的):将一个字节的输出流转化为一个字符的输出流

5.2 转换流的作用

提供字节流和字符流之间的转换

5.3 转换流的使用

  • InputStreamReader

    InputStreamReader第一个 参数放要转换的流,第二个参数为编码集(取决于对应文件的编码集,可以省略,省略则用系统默认。)

public class InputStreamReaderTest {
    @Test
    public void test(){
        InputStreamReader isr = null;
        try {
            FileInputStream fis = new FileInputStream("src\\hello.txt");
            isr = new InputStreamReader(fis,"UTF-8");

            char[] cbuf = new char[5];
            int len;
            while((len = isr.read(cbuf)) != -1){
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(isr !=null){
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

6.字符集

  • ASCII:美国标准信息交换码。用一个字节的7位可以表示。
  • ISO8859-1:拉丁码表,欧洲码表。用一个字节的8位可以表示。
  • GB2312:中国的中文编码表,最多两个字节编码所有字符。
  • GBK:中国的中文编码表升级,融合了更多了中文文字符号。最多两个字节编码。
  • Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符吗。
  • UTF-8:变长的编码方式,可用1-4字节来表示一个字符。

6.标准输入、输出流

6.1 System.in和System.out

1.
System.in:标准的输入流,默认从键盘输如。
System.out:标准的输出流,默认从控制台输出。

2.
System类的setIn(InputStream in)/setOut(PrintStream out)
  • 练习
    /*练习1:从键盘输入字符串,要求将读取到的整行字符串转化成大写输出,然后继续进行输入操作,直至输入“e”,或者"exit"时
    * 退出程序*/
            /*
            * 方法一“使用Scanner实现,调用next()返回一个字符串
            * 方法二:使用System.in实现.System.in-->转换流--->BufferedReader的readline
            * */
    public static void main(String[] args) {

            BufferedReader br =null;
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            br = new BufferedReader(isr);
            while(true){
                System.out.println("请输入一串字符。\n");
                String data = null;
                    data = br.readLine();
                if(data.equalsIgnoreCase("e" )||data.equalsIgnoreCase("exot")){
                    System.out.println("程序结束");
                    break;
                }else{
                    System.out.println(data.toUpperCase());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

6.2 打印流

实现将基本数据类型的数据格式转化为字符转输出

打印流:PrintStream和PrintWriter

  • 提供了一系列重载的Print和Println的方法。

6.3 数据流

将内存中的数据写出到硬盘中或者将硬盘中的数据还原到内存中。

操作基本数据类型和String的数据。

数据流有两个类

  • DataInputStream和DataOutputStream(分别“套接”在InputStream和OutputStream子类的流上。)

    • 作用:用于读取或者写出基本数据类型的变量或字符串
    /**
         * 练习:将内存中的字符串、基本数据类型的变量写出到文件中
         * @throws FileNotFoundException
         */
        @Test
        public void test2() throws FileNotFoundException {
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("src\\data.txt"));
            try {
                dos.writeUTF("huangyuanxin");
                dos.flush();
                dos.writeInt(123);
                dos.flush();
                dos.writeBoolean(true);
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
        }
    
    
       /**
         * 将data.txt中的数据读取
         */
        @Test
        public void test3(){
            DataInputStream dis = null;
            try {
                dis = new DataInputStream(new FileInputStream("src\\data.txt"));
                String name = dis.readUTF();
                int age = dis.readInt();
                Boolean isMale = dis.readBoolean();
                System.out.println("name="+name+"\n"+"age="+age+"\n"+"isMale="+isMale);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(dis != null){
                    try {
                        dis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
  • 注意从内存中写出的顺序是什么,读取到的数据顺序就是什么

DataInputStream中的方法

  • boolean readBoolean()
  • byte readByte()
  • char readChar()
  • float readFloat
  • double readDouble()
  • short readShort()
  • long readLong()
  • int readInt()
  • String readUTF()
  • void readFully(byte[] b)

DataOutputStream的方法

  • 将上面的read改为write。

6.4 对象流

对象流

  • ObjectInputStream
  • ObjectOutputStream

用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把java中的对象写入到数据源中,也能把对象从数据源中还原回来。

序列化

  • 用ObjectOutputStream类保存基本数据类型或对象的机制

反序列化

  • 用ObjectInputStream类读取基本数据类型或对象的机制

注意

  • ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。(即如果不想要序列化某一个属性,就用transient修饰)

对象的序列化

持久化保存数据

  • 对象序列化机制允许把内存中的java对象转化为平台无关的二进制流,从而允许把这种二进制流持久的保存在硬盘上,或通过网络将这种二进制流传输到另外一个网络节点。当其他程序获取了了这种二进制流,就可以恢复成原来的java对象
  • 序列化的好处可以将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输中可被还原。
  • 如果需要让某个对象支持序列化机制,则必须保持对象所属的类及其属性是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一
    • Serializable
    • Externalizable
 /**
     * 序列化的过程
     */
    @Test
    public void test(){
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("src\\object.dat"));
            oos.writeObject(new String("huangyuanxin"));
            oos.flush();//刷新操作。
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

反序列化

将磁盘文件中的对象还原为内存中的一个java对象

/**
     * 反序列化的过程
     */
    @Test
    public void testObjectInputStream(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("src\\object.dat"));
            Object obj = ois.readObject();
            String str = (String)obj;
            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
6.4-2 自定义类的序列化和反序列化
##Person类是有String name和int类型的bean

/**
     * 序列化的过程
     */
    @Test
    public void test() {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("src\\object.dat"));
            oos.writeObject(new String("huangyuanxin"));
            oos.flush();//刷新操作。
            oos.writeObject(new Person("huangyuanxin",18));
            oos.flush();

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

    /**
     * 反序列化的过程
     */
    @Test
    public void testObjectInputStream() {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("src\\object.dat"));
            Object obj = ois.readObject();
            String str = (String) obj;

            Person p = (Person) ois.readObject();
            System.out.println(str);
            System.out.println(p);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

6.5 随机存储文件流

6.5-1 RandomAccessFile类

RandomAccessFile类声明在java.io包下,但直接继承于java.lang.Object类。并且实现了DataInput/DataOutput这两个接口,也就意味着这个类既可以读也可以写。

  • RandomAccessFile类支持“随机访问”的方式,程序可以直接跳到文件的任意地方来读、写文件
    • 支持只访问文件的部分内容
    • 可以向已存在的文件后追加内容。
  • RandomAccessFile对象包含一个记录指针,用以标示当前读写处的位置。
    • RandomAccessFile类对象可以自由移动记录指针。
      • long getFilePointer():获取文件记录指针的当前位置
      • void seek(long pos):将文件记录指针定位到pos位置。

构造器组成

(“文件名(或者文件路径)”/ “mode”)

mode

  • r:以只读方式打开
  • rw:打开以便读取和写入
  • rwd:打开以便读取和写入;同步文件内容的更新
  • rws:打开以便读取和写入;同步文件内容和元数据的更新

注意

  • 如果模式为只读r,则不会创建文件,而是去读取一个已经存在的文件,如果读取的文件不存在则会出现异常。如果模式为rw读写,如果文件不存在则会去创建文件,如果存在则不会创建。
/**
 * 1.RandomAccessFile直接继承于java.lang.object类,实现了DataInput和DataOutput接口
 * 2.RandomAccessFile既可以作为一个输入流,又可以作为一个输出流
 */
public class RandomAccessFileTest {
    @Test
    public void test() {
        RandomAccessFile rafin = null;
        RandomAccessFile rafin2 = null;
        try {
            rafin = new RandomAccessFile(new File("src\\10out.jpg"), "r");
            rafin2 = new RandomAccessFile(new File("src\\10random.jpg"), "rw");

            byte[] buffer = new byte[10];
            int len;
            while ((len = rafin.read(buffer)) != -1) {
                rafin2.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (rafin != null) {
                try {
                    rafin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if (rafin2 != null) {
                    try {
                        rafin2.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }
        }
    }
}
//结果:创建了10Random.jpg的文件
6.5-2 在已存在的文件后面追写内容
 @Test
    public void test2(){
        RandomAccessFile rafin2 = null;
        try {
            rafin2 = new RandomAccessFile("src\\copyhello","rw");
            rafin2.write("RandomAccess".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(rafin2 != null){
                try {
                    rafin2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }
//结果:在copyhello从第一个字符开始覆盖了RandomAccess的字符串。

说明

  • 作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建文件
  • 如果写出到的文件存在,则会对原有文件内容进行覆盖。
6.5-3 在已存在的文件中 -插入-内容
/**
 * 将内容插入到文件角标为pos的位置处
 */
    }
    @Test
    public void test3(){
        RandomAccessFile rafin2 = null;
        try {
            rafin2 = new RandomAccessFile("src\\copyhello","rw");
            rafin2.seek(3);//将指针调到角标为3的位置
            rafin2.write("RandomAccess".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(rafin2 != null){
                try {
                    rafin2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
    
//在copyhello的txt文件第4位数开始插入RandomAccess,其他内容不改变
6.5-4 Random实现数据的插入
@Test
    public void test4(){
        RandomAccessFile raf1 = null;
        try {
            raf1 = new RandomAccessFile("src\\hello.txt","rw");

            raf1.seek(3);//将指针调到角标为3的位置
            //保存指针3后面的所有数据到StringBuilder中
            StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
            byte[] buffer = new byte[20];
            int len;
            while((len = raf1.read(buffer)) != -1){
                builder.append(new String(buffer,0,len));
            }
            //调回指针,写入"xyz"
            raf1.seek(3);
            raf1.write("xyz".getBytes());
            //将StringBuilder的数据写入到文件中
            raf1.write(builder.toString().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(raf1 != null){
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

6.NIO.2中Path、Paths、Files类的使用

  • Java NIO是从Java 1.4版本开始引入的一套新的IO API。可以替代标注你的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。 IO将更加高效的方式进行文件的读写操作

  • Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。

    channel: 通道

java.nio.channels.Channel

FileChannel:处理本地文件

SocketChannelL:TCP网络编程的客户端的Channel

SeverSocketChannel:TCP网络编程的服务器端的Channel

DatagramChannel:UDP网络编程中发送端和接收端的Channel

6.1 Path、Paths、和Files核心API
  • 早期的Java只提供了一个File类来访问文件系统,但File类的功能有限,提供的方法性能不搞。大多数方法在出错时仅返回失败,并不会提供异常信息

  • NIO.2为了弥补这种不足,引入了Path接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。Path可以看成是File类的升级版本,实际引用的资源也可以不存在

  • 在Java7以后,我们可以写

    • import java.nio.file.Path
      import java nio.file.Paths
      Path path = Paths.get("index.html");
      

Path常用方法见API文档

阿帕奇提供了commons-io的一个包提供了许多API,导入到IDEA中后就可以调用使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个圆圈圈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值