JAVA入门————API(常用API)

下面给各位扩展一些JAVA开发中常用的API

文档注释(ApiDoc):

import javax.crypto.spec.PSource;

  • 文档注释是功能级注释,只在三个地方使用,分别是:类,方法,常量上
  • 文档注释可以通过javadoc命令生成手册
  • 在类上使用时用来说明当前类的设计目的和整体功能介绍
  • @author 作者
  • @version 版本号及修改日期
  • @see //参考参见(和哪个类与共同关系的)
  • @since JDK 1.8 最低版本建议,始于哪个版本可以运行
  /**
     * sayHello()方法中使用的问候语
     */
   public static final String INFO = "你好!";
    /**
     * 为给指定的用户添加问候语
     * @param name  字符串(名字)
     * @return 字符串问候语(你好!参数值)
     */
   public String sayHello(String name){
    
    
       return INFO + name;
   }
   public static void main(String[] args) {
    
    
        ApiDocDemo ap = new ApiDocDemo();
        System.out.println(ap.sayHello("邓嘉宁"));
    }

在这里插入图片描述

包装类(Integer):

包装类

  • java8定义了包装类,目的是为了解决基本类型不能直接参与面向对象开发的问题
  • 使得基本类型可以通过包装类的实例以对象的形式存在
  • 其中数组类型的包装类都继承子java.lang.Number
  • 而char和boolean的包装类直接继承自Object
  • Number是一个抽象类,定义了一些方法,目的是让包装类可以将其表示的基本类型转换为其他数字类型
  • JDK5之后推出来了一个新的特性:自动拆装箱
  • 该特性是编译器认可的,当编译器编译源代码时发现有基本类型和引用类型相互赋值时会自动补充代码来完成它们的转换工作,这个过程称之为自动拆装箱
public static void main(String[] args) {
    
    
        /*
            触发自动拆装箱特性,编译器会补充代码将包装类转换为基本类型,下面的代码会变为:
                int w = new Integer(123).intValue();
         */
        int w = new Integer(123);
        /*
            触发编译器自动拆装箱特性,代码会被编译器改为:
                Integer y = Integer.valueOf(123);
         */
        Integer y = 123;

//     基本类型转换为包装类
        int i = 200;
//        java推荐我们使用包装类的静态方法valueOf将基本类型转换为包装类,而不是直接new

        Integer i1 = Integer.valueOf(i);//Integer会重写-128~127之间的整数对象
        Integer i2 = Integer.valueOf(i);
        System.out.println(i1 == i2);//true
        System.out.println(i1.equals(i2));//true

        double dou = 123.123;
        Double dou1 = Double.valueOf(dou);//Double则是直接new
        Double dou2 = Double.valueOf(dou);

        System.out.println(dou1 == dou2);//false
        System.out.println(dou1.equals(dou2));//true

//        包装类转换为基本类型
        int in = i1.intValue();//获取包装类i1对象中表示的基本类型值
        double doub = i1.doubleValue();//将int类型的i1包装类强转成Double类型并赋值给doub
        System.out.println(in);//123
        System.out.println(doub);//123.0

        in = dou1.intValue();//大类型转小类型可能存在精度丢失
        doub = dou1.doubleValue();
        System.out.println(in);//123
        System.out.println(doub);//123.123
    }

文件类(File):

import java.io.File

  • File类的每一个实例可以表示硬盘(文件系统)中的一个文件或目录(实际上表示的是一个抽象路径)
  • 使用File可以做到:
  • 1:访问其表示的文件或目录的属性信息,例如:名字,大小,修改时间等
  • 2:创建和删除文件或目录
  • 3:访问一个目录中的子项
  • 但是File不能访问文件数据
public static void main(String[] args) {
    
    
        File file = new File("./demo.txt");
        //获取文件名
        String name = file.getName();
        System.out.println(name);

        //文件长度  单位字节
        Long len = file.length();
        System.out.println(len+"字符");

        //是否是隐藏
        boolean isHidden = file.isHidden();
        System.out.println("是否隐藏:"+isHidden);

        //是否可读
        boolean cr = file.canRead();
        System.out.println("文件是否可读:"+cr);
        //是否可写
        boolean cw = file.canWrite();
        System.out.println("文件是否可写:"+cw);

    }

String类:

返回当前字符串中指定下标对应的字符

/**
 * char  charAt(int index)
 */
public class CharAtDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "thinking in java";
//        获取第6个字符是什么
        char c = str.charAt(5);
        System.out.println(c);
    }
}

检索当前字符串中给定字符串的位置

/**
 * int indexOf(String str)
 * 检索当前字符串中给定字符串的位置
 * 如果当前字符串不包含给定内容时返回值为-1
 */
public class IndexOfDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "thinking in java";
//        查找in在当前字符串中第一次出现的下标
        int index = str.indexOf("in");
        System.out.println(index);//2
//        从指定位置开始检索第一次出现给定字符串的下标
        index = str.indexOf("in",3);//str:给定字符串  fromlndex:起始检索位置
        System.out.println(index);//5
//        检索最后一次出现给定字符串的位置
        index = str.lastIndexOf("in");
        System.out.println(index);//9
    }
}

返回当前字符串的长度(字符个数)

/**
 * int length()
 * 返回当前字符串的长度(字符个数)
 */
public class LengthDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "我爱Djn(Java)";
        System.out.println("len:"+str.length());

    }
}

正则表达式


import java.net.SecureCacheResponse;
import java.util.Scanner;

/**
 * 正则表达式:
 * 正则表达式是用来字描述符串的内容格式,使用它通常用来匹配一个字符串的内容是否符合格式要求
 * 基本语法:
 * []:表示一个字符,该字符可以是[]中指定的内容
 * 注意:[]当中的内容必须小的在前大的在后,不可以颠倒
 * 例如:
 * [abc]:这个字符可以是a或b或c
 * [a-z]:表示任意一个小写字母
 * [a-zA-Z]:表示任意一个字母(大小写均可)
 * [a-zA-Z0-9]:表示任意一个数字字母下划线
 * [^abc]:该字符只要不是a或b或c
 *
 * 预定义字符:
 *  . :表示任意一个字符,范围没有限制
 * \d:表示任意一个数字,等同于[0-9]
 * \w:表示任意一个单词字符,等同于[a-zA-Z0-9]
 * \s:表示任意一个空白字符
 * \D:不是数字
 * \W:不是单词字符
 * \S:不是空白字符
 *
 * 量词:
 * ?:表示前面的内容出现0-1此
 * 例如:
 * [abc]?  可以匹配:a或b或c 或什么也不写
 *
 *  +:表示[]的内容出现1此以上
 *  [abc]+ 可以匹配:aaaaaaaaa....或abcabcabcabcabca......
 *          但是不能匹配:什么都不写或[]不存在的字符
 *  *:表示前面的内容出现任意次(0-多次)
 *    匹配内容与+一致,只是可以一次都不写
 *
 * {n}:便是前面的内容出现n次
 * 例如:
 * [abc]{3} 可以匹配:aaa 或 bbb 或 aab
 *          不能匹配:aaaa 或 aaf
 *
 *  {n,m}:表示前面的内容出现最少n次最多m次
 *  [abc]{3,5}  可以匹配:aaa 或 abcab 或abcc
 *              不能匹配:aaaaaa 或 aabbd
 *
 *  {n, }:表示前面的内容出现n次以上(含n次)
 *  [abc]{3,}  可以匹配:aaa  或  aaaaaa.... 或abcabcabcabcabcacab.....
 *             不可以匹配:aa 或 abbdaw
 *
 *  ()用于分组,是将括号内的内容看作是一个整体
 *  例如:
 *   (abc){3} 表示abc整体出现3次  可以匹配:abcabcabc
 *                              不能匹配:aaa  或 abcabc
 *
 *  (abc|def){3} 表示abc或def整体出现3次
 *
 * String支持正则表达式的方法之一:
 * boolean matches(String regex)
 * 使用给定的正则表达式验证当前字符串是否满足格式要求,满足则返回true,否则返回false
 */
public class MatchesDemo {
    
    
    public static void main(String[] args) {
    
    
        /*
            邮箱的正则表达式
            用户名@域名
            [email protected]

            [a-zA-Z0-9_]+@[a-zA-Z0-9]+(\.[a-zA-Z]+)+
         */
        Scanner sc = new Scanner(System.in);
        String mail = sc.next();//接收控制台输入的邮箱
        String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//限制邮箱格式
        boolean match = mail.matches(regex);//判断是否符合正则表达式格式
        if (match){
    
    
            System.out.println("格式正确");
        }else{
    
    
            System.out.println("格式错误");
        }
    }
}

String支持正则表达式的方法

/* 
 * String replaceAll(String regex,String str)
 * 将当前字符串中满足正则表达式的部分替换为给定内容
 */
public class ReplaceAllDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "abc123def456ghi";
        //将当前字符串中的数字部分替换为“#JDdwfEN#”
//        regex:替换的0-9之间的连续的字符   replacement:替换的给定字符#JDdwfEN#
        str = str.replaceAll("[0-9]+","#JDdwfEN#");
        System.out.println(str);

    }
}
import java.util.Arrays;

/**
 * String支持正则表达式的方法二:
 * String[]   split(String regex)
 * 将当前字符串按照满足正则表达式的部分进行拆分,将拆分后的每个部位以数组形式返回
 */
public class SplitDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "abc123def456ghi";
        //按照数组部分进行拆分,获取其中每部分字母
        String[] arr = str.split("[0-9]+");//拆除数字部分
        System.out.println(arr.length);//输出数组长度
        System.out.println(Arrays.toString(arr));//输出数组元素

//        如果连续遇到拆分项,则会拆分出一个空字符串,但是在字符串末尾连续遇到则忽略
        str = ",,,123,,,4556,122,,,,";
        arr = str.split(",");
        System.out.println(Arrays.toString(arr));//[ , , ,123, , ,4556,122]

        str = "123.456.798.023";
        arr = str.split("\\.");// .在正则表达式中表示任意字符,所以要用\\告诉它这个是.
        System.out.println(Arrays.toString(arr));
    }
}

截取字符串中指定位置字符

/**
 * String substring(int start,int end)
 * 截取当前字符串中指定范围的字符串,start,end时开始和结束位置的下标
 * 注意:在Java API中通常使用两个数字表示范围时,都不含头不含尾
 */
public class SubstringDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "www.tedu.cn";
//        截取域名部分
        System.out.println(str.substring(4,8));//tedu
//        重载的substring方法可以从指定位置和截取到字符串末尾
        System.out.println(str.substring(4));//tedu.cn
    }

和谐用语

public static void main(String[] args) {
    
    
        String regex = "(wqnmlgb|dsb|cnm|nc|fw|wrsndm|nmsl|djb)";
        String message = "wqnmlgb!你个dsb,你怎么这么的nc!你就是一个djb";
        //梦露baby
        message = message.replaceAll(regex,"***");
        System.out.println(message);
    }

判断当前字符串是否是以…开头或以…结尾

/**
 * 判断当前字符串是否是以给定内容开头或结尾的
 * boolean startsWith(String str)
 * boolean endsWith(String str)
 */
public class StartsWithDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "www.tedu.com";
//        查看str是否是以“www.”开头的
        System.out.println(str.startsWith("www."));//开头
//        查看str是不是以“.cn”结尾的
        System.out.println(str.endsWith(".cn"));//结尾
    }
}

修改String字符:

String 是不可变的字符串 但是我们常常是需要它改变的 话不多说上代码告诉你如何在源对象上做改变

package string;

import javafx.event.EventDispatchChain;

/**
 * java.lang.StringBuilder
 * 专门用来修改String的一个API,内部维护一个可变的char数组,修改都是在这个数组上进行
 * 内部会自动扩容,修改速度和性能开销优异,并且提供了修改字符串的常见操作对一个的方法:增删改插
 */
public class StringBuilderDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "好好学习Java";

                    /*增*/
        /*
           原始:好好学习java
           增加后:好好学习java,为了找个好工作
            append:追加内容
         */
//        内部默认表示一个空字符串
//        StringBuilder br = new StringBuilder();

        StringBuilder  br = new StringBuilder(str);//   不是线程安全
//        StringBuffer  bf = new StringBuffer(str);     是线程安全
        br.append(",为了找个好工作!");
        System.out.println(br);//输出StringBuilder

//        通过调用toString方法将StringBuilder内容以字符串形式返回
        str = br.toString();
        System.out.println(str);

                    /*改*/
        /*
           原始:好好学习java,为了找个好工作!
           修改后:好好学习java,就是为了改变世界!
           replace:替换部分内容
           start:内容替换的起始下标
           end:内容替换的结束下标
           str:要替换成为的内容
         */
        br.replace(9,16,"就是为了改变世界");
        System.out.println(br);

                    /*删*/
        /*
            原始:好好学习java,就是为了改变世界!
            删除后:,就是为了改变世界!
            delete:删除部分内容
         */
        br.delete(0,8);
        System.out.println(br);

                /*插*/
        /*
            原始:,就是为了改变世界
            插入后:活着,就是为了改变世界
            insert:插入操作
         */
        br.insert(0,"活着");
        System.out.println(br);

                /*反转(反序)*/
        /*
           原始:活着,就是为了改变世界!
           反转后:!界世变改了为是就,着活
           reverse():倒序打印字符串
         */
        br.reverse();
        System.out.println(br);

        /*性能测试*/
        StringBuilder a = new StringBuilder("a");
        for (int i=0;i<1000;i++){
    
    
            a.append("a");
        }
        System.out.println("执行完毕!");
    }
    /**
     * 总结
     * StringBuilder是可变字符串,字符串的内容计算,建议:
     * 采用StringBuilder实现,这样性能会好一些
     * java的字符串连接的过程是利用StringBuilder实现的
     *          String s = "AB";   String s1 = s + "DE" + 1;
     *          String s1 = new StringBuilder(s).append("DE")
     *                      .append(1).toString();
     * StringBuffer 和 StringBuilder
     *      StringBuffer是:线程安全的,同步处理的,性能稍慢
     *      StringBuilder是:非线程安全的,并发处理,性能稍快
     */
}

字符串String知识扩展:

/**
 * 字符串
 */
public class StringDemo {
    
    
    public static void main(String[] args) {
    
    
    /*
        java为了提高性能,静态字符串(字面量/常量/常量连接的结果)在常量池中,并尽量使用同一个对象
        字符串是不变对象,因为在它的类中他是final类型的char数组
     */
        String str = "abc";//abc 是字面量
//        基本类型赋的值都叫字面量
        int a = 1;
//        此处由s1使用该字面量创建过字符串对象,因此s2 s3都会复用这个对象(JDK1.8以后)
        String s1 = "123asd";
        String s2 = "123asd";
        String s3 = "123asd";
//        此处比较的是三个对象之间的地址是否一致,而不是字面量是否一样
        System.out.println(s1 == s2);//true
        System.out.println(s2 == s3);//true
        System.out.println(s3 == s1);//true
//        创建了一个新的s2对象(123asd!)
        s2 = s2 + "!";
        System.out.println(s2 == s1);//false

        String s4 = new String("123asd");
        System.out.println(s1 == s4);//false,地址不相同,因为new会让系统创建一个新的对象
        System.out.println(s1.equals(s4));//true,equals比较的是字符串的内容
        //实际开发中比较字符串的需求都是比较内容,都应当使用equals进行比较!!!

        /*
            这里触发了编译器的一个特点:
                编译器在编译源代码时,只要一个计算表达式可以在编译期间确定结果,
                编译器一定进行计算,并将结果编译到字节码文件中,
                因此下面的代码会被编译器改为
                 String s5 = "123asd";
                因此s5在JVM进行执行时会复用s1对象
         */
        String s5 = "123" + "asd";
        System.out.println(s1 == s5);//true
    }

截取当前字符串中指定范围的字符串

/**
 * String substring(int start,int end)
 * 截取当前字符串中指定范围的字符串,start,end时开始和结束位置的下标
 * 注意:在Java API中通常使用两个数字表示范围时,都不含头不含尾
 */
public class SubstringDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "www.tedu.cn";
//        截取域名部分
        System.out.println(str.substring(4,8));//tedu
//        重载的substring方法可以从指定位置和截取到字符串末尾
        System.out.println(str.substring(4));//tedu.cn
    }
}

将字符串中的英文转换为大/小写:

/**
 * 将当前字符中的英文部分转换为全大写或全小写
 * String toUpperCase
 * String toLowerCase
 */
public class ToUpperCaseDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "我爱DengJiaNing";
        System.out.println(str);
//        英文字母全大写
        System.out.println(str.toUpperCase());
//        英文字母全小写
        System.out.println(str.toLowerCase());
  

去除字符串两端空白:

import javax.crypto.spec.PSource;

/**
 * 去除字符串两边空白
 */
public class TrimDemo {
    
    
    public static void main(String[] args) {
    
    
        String str = "   Hello  ";
        System.out.println(str);
        String  trim = str.trim();
        System.out.println(trim);
    }
}

基本类型转换为引用类型:

/**
 * String 提供了一组重载的valueOf方法,作用是将其他类型转换为String
 * 注意:这些valueOf都是静态方法(需要用 类名. 来访问)
 */
public class ValueOfDemo {
    
    
    public static void main(String[] args) {
    
    
        int a = 123;
        String str = String.valueOf(a);

        double dou = 123.123;
        String str2 = String.valueOf(dou);

        System.out.println(str);
        System.out.println(str2);

        String str3 = a + "";
    }
}

目录类(File):

Object(所有类的超类):

Object是所有类的顶级超类,里面有几个经常被子类重写的方法,其中包括toString和equals

package object;

import java.util.Objects;

/**
 * 使用当前类测试常被子类重写的Object相关方法
 *
 * 当前类表示直角坐标系上的一个点
 */
public class Point {
    
    
    private int x;
    private int y;

    public Point(int x, int y) {
    
    
        this.x = x;
        this.y = y;
    }


    public int getX() {
    
    
        return x;
    }

    public void setX(int x) {
    
    
        this.x = x;
    }

    public int getY() {
    
    
        return y;
    }

    public void setY(int y) {
    
    
        this.y = y;
    }

    /**
     * 重写toString让控制台输出Point类型的p对象的具体属性
      * @return
     */
    @Override
    public String toString() {
    
    
        return "Point{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }

    @Override
    public boolean equals(Object o) {
    
    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Point point = (Point) o;
        return x == point.x &&
                y == point.y;
    }

    @Override
    public int hashCode() {
    
    
        return Objects.hash(x, y);
    }
}

/**
 * Object是所有类的顶级超类,里面有几个经常被子类重写的方法,其中包括toString和equals
 */
public class Demo {
    
    
    public static void main(String[] args) {
    
    
        Point p = new Point(1,2);
        /*
            Object已经实现了toString方法,直接继承下来时返回的字符串内容为当前对象
            的地址信息,格式为:类名@地址
            toString方法实际开发中很少直接写代码去调用它,都是在不经意间被自动执行的
            例如在是圆通System.out.println()输出时.与字符串连接操作时.
         */
//        String str = p.toString();
//        System.out.println(str);
//       System.out.println(Object obj);输出给定对象toString返回的字符串到控制台
        System.out.println(p);
        String line = "这是一个"+p;
        System.out.println(line);

        Point p2 = new Point(1,2);
        System.out.println(p2);

        /*
            对于引用类型而言,变量保存的值时对象的地址
            ==比较是比较两个变量的值是否相等,因此对于引用类型而言就是比较地址是否相等
            那么意思就是比较是否为同一个对象

            equals是Object定义的另一个方法,意图是比较两个对象的内容是否相同,
            但是如果子类不重写这个方法,则没有实际意义,因为Object实现时内部仍然是用==比较的!
         */
        System.out.println(p == p2);//false
        System.out.println(p.equals(p2));//true
    }
}

lambda表达式:

JDK8之后,jaba支持了lambda表达式这个特性

import java.io.File;
import java.io.FileFilter;

/**
 * JDK8之后,jaba支持了lambda表达式这个特性
 * lambda可以用更精简的代码创建匿名内部类,但是该匿名内部类实现的接口只能有一个抽象方法
 * 否则无法使用
 *
 * 语法:
 * (参数列表)->{
 *     方法体
 * }
 */
public class LambdaDemo {
    
    
    public static void main(String[] args) {
    
    
        //常规匿名内部类
        FileFilter filter = new FileFilter() {
    
    
            @Override
            public boolean accept(File file) {
    
    
                return file.getName().contains("a");
            }
        };

        //lambda表达式经典样式
        FileFilter filter2 = (File file)->{
    
    
            return  file.getName().contains("a");
        };

        //lambda表达式可以不写参数类型,只需指定参数名即可
        FileFilter filter3 = ( file)->{
    
    
            return  file.getName().contains("a");
        };

        /*
            如果方法体中只有一行代码时,方法体的“{}”是可以忽略不写的
            如果该方法需要返回值,则忽略{}的同时,return关键字也必须一同忽略不写
         */
        FileFilter filter4 = (file)-> file.getName().contains("a");

        //若只有一个参数的时候()可以忽略
        FileFilter filter5 = file -> file.getName().contains("a");
    }
}

		//过滤子项名含“a”的子项
        File dir = new File(".");
        if (dir.isDirectory()){
    
    
            File[] subs = dir.listFiles(file -> file.getName().contains("a"));
        }

RAF读取文件数据:

此方法是专门用来读写文件数据的

package raf;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;

/**         随机   访问  文件
 * java.io.RandomAccessFile
 * RAF是专门用来读写文件的API,其基于指针对文件任意位置进行读写操作,因此读写方式灵活
 */
public class RAFDemo1 {
    
    
    public static void main(String[] args) throws FileNotFoundException {
    
    
        /*
            常用构造器
            RandomAccessFile(File file,String mode);
            RandomAccessFile(String fileName,String mode);
            第一个参数为要操作的文件,第二个参数为操作模式
            操作模式是一个字符串,支持两个值:
            “r”:只读模式,仅对文件做读取操作  r:read读
            “rw”:读写模式,对文件即可读又可写,w:write写

            RAF在创建时,若指定的文件不存在,则根据操作模式不同,结果不同
            如果指定的是rw模式,则会将该文件创建出来
            如果指定的是r模式,则会爆出异常FileNotFoundException,告知该文件不存在!
         */
        //想对当前目录下的raf.dat文件进行操作
//        File file = new File("./raf.dat");
//        RandomAccessFile raf = new RandomAccessFile(file,"rw");

        RandomAccessFile ref = new RandomAccessFile("./raf.dat","rw");
        
		/*
            void write(int b)
            向文件中写入一个字节,写入的是给定的int值所对应的2进制的“低八位“

            int  1
            二进制:00000000 00000000 00000000 00000001
         */
        ref.write(1);//00000001
        ref.write(2);//00000010
        
        ref.close();//当使用RAF读写完毕后,最终要调用close方法释放资源
    }
}

从文件中读取资源

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 从文件中读取数据
 */
public class RAFDemo2 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //从当前目录下的ref.dat文件中读取字节
        RandomAccessFile ref = new RandomAccessFile("./ref.dat","r");
        /*
              int read()
              从文件中读取1个字节,返回值为int型,该int值对应的2进制的”低八位“就是本次读取出来的字节内容
              如果返回的int值是-1则表示读取到了文件的末尾(EOF)
              EOF:end of file 文件末尾
         */
        /*
             ref.dat 文件内容
             000000001  00000010
         */
        int d = ref.read();//00000001
        System.out.println(d);//1

        d = ref.read();//00000010
        System.out.println(d);//2

        d = ref.read();//11111111 11111111 11111111 11111111
        System.out.println(d);//-1 表示已经是文件末尾了!

        ref.close();//结束读写,释放资源

    }
}

向文件中 写入/读取 文本数据

写入:

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

/**
 * 向文件中写入文本数据
 */
public class WriteStringDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
        RandomAccessFile raf = new RandomAccessFile("./wyy.txt","rw");
        String line = "让我再看你一眼,从南到北,像是北五环路,蒙住的双眼";
    /*
     创建字符集名字:
        utf-8:万国码(对应的就是unicode),其中英文数字符号为单字节(asc),中文占三个字节
        gbk:国标编码,其中英文数字符号占单字节(asc),中文占2字节
        iso8859-1:欧洲字符集,不支持中文

     两种设置编码格式的方法:
      line.getBytes(StandardCharsets.UTF_8);
       line.getBytes("UTF-8");
     */
        //当指定的字符集名字拼写错误时会抛出:UnsupportedEncodingException
        byte[] data = line.getBytes("UTF-8");//字符集名字大小写无所谓
        raf.write(data);
        raf.close();//结束读写 释放资源
    }
}

读取文件中的资源,转换为字符串

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 从文件中读取文本数据
 */
public class ReadStringDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
        RandomAccessFile raf = new RandomAccessFile("./wyy.txt","r");
        long len = raf.length();//通过RAF获取其操作的文件的长度(单位是字节)
        //一次性将文件中所有的字节都读取回来
        byte[] data = new byte[(int)len];
        raf.read(data);//将数据读取到数组中
        //将字节数组还原为字符串,使用String的构造方法,且设置编码格式
        String line = new String(data,"UTF-8");
        System.out.println(line);
        raf.close();//结束读写,释放资源
    }
}

ctrl+c/v的原理:


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 复制文件
 */
public class CopyDemo {
    
    
    public static void main(String[] args) throws IOException {
    
    
//        读取被复制的文件
        RandomAccessFile src = new RandomAccessFile("./wxy.png","r");
//          读写赋值的文件
        RandomAccessFile desc = new RandomAccessFile("./raf.dat","rw");
        /*
            以读写第一个字节为例
            源文件内容
             10011010 00101101 00111101 10100010 10010101.....

            d = src.read()后,d的值如下
            int d:00000000 00000000 00000000 10011010

           desc。write(d)后,赋值文件内容如下
           复制文件
           10011010 00101101 00111101 10100010 10010101.....
         */
        int d;
        while ((d = src.read()) != -1) {
    
    
            desc.write(d);
        }
        System.out.println("复制完毕");
        src.close();
        desc.close();
    }
}
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 通过提高每次读写的数据量,减少实际读写的次数可以提高读写效率
 */
public class CopyDemo2 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //读取要被复制的图片/文件 路径
        RandomAccessFile src = new RandomAccessFile("./wxy.png","r");
        //读写要复制给的文件路径
        RandomAccessFile desc = new RandomAccessFile("./wxyTwo.png","rw");

        /*
            RandomAccessFile提供了块读写的方法
            读:
            int read(byte[] data)
            一次性从文件中读取给定的字节数组总长度的字节亮并装入到该数组中,返回值表示实际读取
            到的字节量.如果返回值为-1则表示EOF.

            例如
            文件数据(总共6个字节):
            11011101 10101101 00110011 11010010 11001101 00111101

            块读:
            byte数组:  byte[] data = new byte[10];  创建能保存10个字节的数组
            int len=0; 表示每次实际读取到的字节量

            读取前
            data:[00000000,00000000,00000000,00000000]
            len:0

            len = src.read(data);//一次性从文件中读取4个字节并存入该数组
            读取后:
            data:[11011101,10101101,00110011,11010010]
            len:4



            块写操作
            void write(byte[] data)
            一次性将给定的字节数组中的所有字节写入文件
            例如:
            data:[11011101,10101101,00110011,11010010]

            desc.write(data);
            复制的文件内容:
            11011101 10101101 00110011 11010010
         */
        /*
            8位2进制:00000000  1byte  1字节
            1024byte  1kb
            1024kb    1mb
            1024mb    1gb
            1024gb    1tb
         */
        byte[] data = new byte[1024*10];//每次读取1kb
        int len = 0;//记录每次实际读取到的字节量
        long start = System.currentTimeMillis();//获取当前系统读取事件的毫秒值
        //从源文件中一次读取1kb数据存入data中
        while ((len = src.read(data)) != -1){
    
    
            desc.write(data,0,len);//将读取的1kb数据一次性写入新的desc文件中
        }
        long end = System.currentTimeMillis();
        System.out.println("复制完毕!耗时:"+(end-start));
        src.close();
        desc.close();
    }
}

简易记事本工具

import javax.sound.midi.Soundbank;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Scanner;

/**
 * 简易记事本工具
 * 程序启动后要求用户输入一个文件名,然后对该文件进行写操作
 * 之后用户输入的[每一行]字符串都写入该文件中,写入文件的数据不用考虑换行问题
 * 当用户单独输入"EXIT/exit"时程序退出
 */
public class Note {
    
    
    public static void main(String[] args) throws IOException {
    
    
        Scanner sc= new Scanner(System.in);
        System.out.println("请输入文件名");
        String input = sc.nextLine();
        File file = new File("./"+input+".txt");
        RandomAccessFile ra = null;
        if (file.isDirectory()){
    
    
            System.out.println("文件已存在");
        }else{
    
    
            file.createNewFile();//创建文件名
            ra = new RandomAccessFile(file,"rw");
            System.out.println("文件以创建,请输入文本(输入EXIT结束)");
            while (true){
    
    
                String wr = sc.nextLine();
                //当字符串字面量equals一个变量时,要用下面的方式判断,避免空指针的发生
                if ("EXIT".equalsIgnoreCase(wr)){
    
    //wr时null时,反过来写就会空指针!
                    System.out.println("程序退出");
                    break;
                }
                    byte[] data = wr.getBytes("UTF-8");
                    ra.write(data);
            }
        }
        ra.close();
    }
}

读写基本类型数据,以及RAF的指针操作


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * 读写基本类型数据,以及RAF的指针操作
 */
public class RAFdemo3 {
    
    
    public static void main(String[] args) throws IOException {
    
    
        RandomAccessFile raf = new RandomAccessFile("./raf.dat","rw");
        /*
            long   getFilePointer()
            获取当前RAF的指针位置
         */
        System.out.println("pos:"+raf.getFilePointer());

        //将一个int值写入文件中
        int i = Integer.MAX_VALUE;
        /*
             i的2进制:
             01111111 11111111 11111111 11111111
                 1        2        3       4
             i>>>8    ******** ******** ********

         */
        raf.write(i>>>24);
        raf.write(i>>>16);
        raf.write(i>>>8);
        raf.write(i);

        /*简易写法(连续写4字节,将int/double/long对应的2进制写入文件,等同上面4句)*/
        //RAF提供了方便写出基本类型的相关方法
        raf.writeInt(i);
        raf.writeDouble(123.123);
        raf.writeLong(789L);
        System.out.println("写出完毕");

        /*
            void seek(long pos);
            移动文件中指针位置
         */
        //移动文件中指针的位置(起始位置是第一字节的位置)
        raf.seek(0);

       int d = raf.readInt();
       System.out.println(d);
       System.out.println("pos:"+raf.getFilePointer());

       /*
             注意,这些读取基本类型的方法内部都是连续读取若干字符然后还原对应的基本类型
            只要他们在连续读取字节的过程中到了文件末尾,而读取的字节数量还不足时就会抛出
            EOFException,告知读取过程中到了文件末尾,并不会用返回-1表示文件末尾!
        */
        //将都变了值改动成234.234
        //1:先将指针移动到double的第一个字节位置
        raf.seek(8);
        //2:重写写入一个double值覆盖原来double的8字节
        raf.writeDouble(234.234);
        raf.seek(8);
        double dou = raf.readDouble();
        System.out.println(dou);


       raf.close();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_54177999/article/details/115164511