【Java高级特性】java学习之旅33-IO流

File类

文件类:表示目录和文件的类

是Java中io流的基础类

常用的方法:

  1. 有参构造方法:File(String pathname)//pathname可以填写绝对路径或者相对路径
File file = new File("E:\\test\\hello.txt");
  1. 判断是否是文件 isFile()
System.out.println(file.isFile());//true
  1. 判断是否是目录 isDirectory()
System.out.println(file.isDirectory());//false
  1. 判断文件或者目录是否存在 exist()
System.out.println(file.exists());//true
  1. 使用file对象创建一个文件 createNewFile()
//创建新的文件时,所包含的目录必须已经创建,否则会报错
try{
    file.createNewFile();
} catch (IOException e) {
    e.printStackTrace();
}
  1. 创建目录 mkdir()
//创建目录时,传入的参数只到目录
file.mkdir();//创建目录
file.mkdirs();//创建多重目录
  1. 获取文件的字节大小 length()
System.out.println(file.length());
  1. 重命名文件并保存内容 renameTo()
file.renameTo(new File("E:\\test\\hi.txt"));
  1. 获取文件名 getName()
Systen.out.println(file.getName());
  1. 获取相对路径 getPath()
System.out.println(file.getPath());
  1. 获取绝对路径 getAbsolutePath()
System.out.println(file.getAbsulutePath());
  1. 删除
file.delete();

//当系统回收的时候删除该文件
file.deleteOnExit();

绝对路径和相对路径

绝对路径: 文件在系统硬盘中的真实全路径

相对路径: 相对项目路径,子路径

  1. ./ 从当前目录开始,可以省略不写
  2. …/ 上一级目录
  3. / 根目录

IO流概念

输入输出流:可以实现将系统中的文件读入到java程序中,将java程序中的数据写出到系统文件。

输入input, 输出output

IO流分类:

1. 字节流

抽象类:InputStream  实现类:FileInputStream 、BufferedInputStream
抽象类:OutputStream 实现类:FileInputStream、BufferedOutputStream

2. 字符流

抽象类:Reader 实现类:FileReader、BufferedReader
抽象类:Writer 实现类:FileWriter、BufferedWriter

3. 对象流(继承字节流)

ObjectInputStream
ObjectOutputStream

4. 二进制流(继承字节流)

DataInputStream
DateOutputStream

5. 转换流

InputStreamReader
OutputStreamWriter

字节流和字符流的选择:

  1. 字符编写的文件可以使用字节流和字符流,推荐使用字符流,效率较高并且保证不乱码
  2. 字节编写的文件可以使用字节流
  3. 使用记事本打开文件,不乱码的是字符文件。

IO流的使用

FileInputStream 字节输入流

常用方法:

  1. 构造方法:
//根据File对象创建输入流
File file = new File("test.txt");
// 创建输入流对象父类引用指向子类
InputStream is = new FileInputStream(file);

//根据文件路径创建输入流
InputStream is = new FileInputStream("test.txt");
  1. 按字节读取 read() 没读到内容返回-1,正常的返回值是字节数
/**
* 按字节读取
*       1.每次读取一个字节
*       2. 中文读取乱码
*/ 
InputStream is = new FileInputStream("test.txt");
int result = 0;
while((result = is.read()) != -1) {
    System.out.print((char)result);
}

is.close();
  1. 读取到指定的byte数组中 read(byte[] data)
/**
* 按字节读取文件
*       1. 将字节内容读取到指定数组
*       2. 一定程度解决了中文乱码,提高了读取速度
*/
InputStream is = new FileInputStream("test.txt");

byte[] data = new byte[512];

int length = 0;
while((length = is.read(data)) != -1) {
//使用读取到的内容创建字符串对象,不包含数组中空内容,
//String的构造方法里面可以放入byte型数组
    System.out.println(new String(data, 0, length)
}

is.close();
  1. 获取可读内容的大小:available()
/**
* 一次性读完整个内容
*/
InputStream is = new FileInputStream("test.txt");

byte[] data = new byte[is.available()];

is.read(data);

System.out.println(new String(data));

is.close();
  1. 关闭资源 close()

FileOutputStream 字符输出流

常用方法:

  1. 构造方法(与输入流相似)
  2. 按字节输出:write(int b)
/**
* 输出一个字节
*       1. 出现中文乱码
*/
OutputStream os = new FileOutputStream("test.txt");

String str = "hello world 你好 世界";

for(char c : str.toCharArray()) {
    os.write(c);
}
os.close();
  1. 按字节数组输出: write(byte[] data)
OutputStream os = new FileOutputStream("test.txt");

String str = "hello world 你好 世界";
//字符串获得byte型数组
os.write(str.getBytes());

os.close();
  1. 关闭资源

字节对拷流

  1. 拷贝文本
public static void main(String[] args) throws IOException{

FileInputStream fis = new FileInputStream("test.txt");

FileOutputStream fos = new FileOutputStream("test_copy.txt");

byte[] data = new byte[512];
int length = 0;

//read返回字节数量,截取从0到指定长度的字节数组
while((length = fis.read(data)) != -1){
    fos.write(data,0,length);
}

fos.close();
fis.close();
}
  1. 拷贝图片
public static void main(String[] args){
    
    InputStream is = new FileInputStream("img\\img1.jpeg");
    OutputStream os = new FileOutputStream("img\\img1_copy.jpeg");
    
    byte[] data = new byte[512];
    
    int length = 0;
    while((length = is.read(data))!= -1){
        os.write(data, 0, length);
    }
    
    os.close();
    id.close();
    
}
BufferedInputStream: 字节缓冲输入流
BufferedOutputStream: 字节缓冲输出流

字节缓冲流、包装流、管道流。实现了字节流的再包装、底层实现了缓冲技术提高了效率。

常用方法:

  1. 构造方法:
FileInputStream fis = FileInputStream("test.txt");
FileOutputStream fos = new FileOutputStream("test_copy.txt");
//管道输入流中放入输入流对象
BufferedInputStream bis = new BufferedInputStream(fis);
//管道输出流中放入输出流对象
BufferedOutputStream bos = new BufferedOutputStream(fos);
  1. 读写方法 read(byte[] data), write(byte[] data, int set, int off)
//以上构造方法
byte[] data = new byte[512];
int length = 0;
while((length = bis.read(data)) != -1) {
    bos.write(data, 0, length);
}
bos.close();
bis.close();
fos.close();
fis.close();
  1. 清空缓冲区:flush()
bos.flush();

注意:

  1. 如果输出流不关闭,可能导致最后没有填满缓冲区的数据丢失
  2. 缓冲流输出,会将数据保存到缓冲区,缓冲区存放满才会将内容输出到文件
  3. 也可以使用flush()方法将缓冲区内同强制输出
FileReader 字符输入流

常用方法:

  1. 构造方法:
//利用File对象创建
Reader reader = new FileReader(new File("test.txt"));
//字符串对象创建对象
Reader reader = new FileReader("test.txt");
  1. 按字符读取 read()
Reader reader = new FileReader(new File("test.txt"));

int result = reader.read();

System.out.println((char)result);

reader.close();
  1. 按照字符数组读取:read(char[] data)
Reader reader = new FileReader(new File("test.txt"));
char[] data = new char[512];

int length = reader.read(data);
System.out.println(length);

System.out.println(new String(data, 0, length));

reader.close();
FileWriter 字符输出流

常用方法:

  1. 构造方法
FileWriter(File file)
FileWriter(String pathname)
  1. 写一个字符
write()
  1. 写一个字符数组
write(char[] data)
  1. 写一个字符串
//String类的底层实现是char[] 数组所以可以放字符串
write(String data)
  1. 关闭资源
close()
  1. 清空缓存区中的内容
flush()

例:

String str = "Hello World 你好 世界";

Writer writer = new FileWriter("test.txt");

writer.write(str.toCharArray());

writer.close();
//writer.flush();

注意事项

  1. FileWriter从OutputStreamWriter继承了缓存系列方法
  2. 可以使用flush()方法清空缓存区的内容
  3. 如果不关闭字符输出流,可能导致最终缓存区内容丢失
字符对拷流
FileReader fr = new FileReader("test.txt");

FileWriter fw = new FileWriter("test_copy.txt");

char[] data = new char[512];
int length = 0;

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

fw.close();
fr.close();
BufferReader: 字符输入缓冲流
BufferWriter: 字符输出缓冲流

字符缓冲流,底层实现了缓冲技术,提高了效率

常用方法:

  1. 构造方法:
FileReader fr = new FileReader("test.txt");
FileWriter fw = new FileWriter("test_copy.txt");

BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
  1. 读取方法:read(), read(char[] data), write(), write(char[] data)
char[] data = new char[512];

int length = 0;
while((length = br.read(data))!= -1){
    bw.write(data, 0, length);
}
  1. 读一整行 readLine(),输出换行:newLine()
String data = null;
while((data = br.readLine()) != null){
    bw.write(data);
    bw.newLine();
}
  1. 清空缓冲区:flush(),关闭资源 close()
bw.close();
br.close();

注意:
字符缓冲流可以实现整行的读取

InputStreamReader、OutputStreamWriter 转换流

解决字符乱码的问题

注意:

  1. 只能转换成缓冲字符流
  2. 源文件字符编码决定输入流的字符编码
  3. 目标文件字符编码决定输出流的字符编码
/**
* 将gbk文件拷贝成utf8文件
* 如果直接使用字符流拷贝,会出现乱码,因为源文件和目标文件的字符编码不一致。
*/
FileReader fr = new FileReader("doc_gbk.txt");
FileWriter fw = new FileWriter("doc_utf8.txt");

BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);

String line = null;
while((line = br.readLine()) != null) {
    System.out.println(line);
    bw.write(line);
    bw.newLine();
}

bw.close();
br.close();
fw.close();
fr.close();

转换编码方式

//1. 创建字节流
FileInputStream fis = new FileInputStream("doc_gbk.txt");
//2.使用字节流创建转换流,此时指定字符编码
InputStreamReader isr = new InputStreamReader(fis, "gbk");
//3.使用转换流创建缓冲字符流
BufferedReader br = new BufferedReader(isr);

//简写输出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("doc_utf8"),"utf-8"));

String line = null;
while((line = br.readLine()) != null){
    System.out.println(line);
    bw.write(line);
    bw.newLine();
}

bw.close();
br.close();
isr.close();
fis.close();
apache commons-io.jar

apache.org 下

常用的工具类:

IOUtils

  1. 简化对拷流
FileReader fr = new FileReader("test.txt");
FileWriter fw = new FileWriter("test_copy.txt");

IOUtils.copy(fr, fw);
fw.close();
fr.close();

  1. 复制文件:
FileUtils.copyFile(new File("test.txt"), new File("test_copy.txt"));
  1. 将文件的内容读成字符串:
String content = FileUtils.readFileToString(new File("test.txt"),"utf-8");
  1. 将字符串的内容输入到文件
//最后一个参数true就是允许文件内容不断叠加,不删除
FileUtils.writeStringToFile(new File("test.txt"), "hello world", "utf-8" , true);
  1. 将网络上URL的地址复制文件
FileUtils.copyURLtoFile(new URL("https://timgsa.baidu.com/timg"), new File("xm.jpg"));

训练:

  1. 将99乘法表输出到文件99table.txt
    FileOutputStream fos = new FileOutputStream("99table.txt");
    
    for(int i = 1; i <= 9; i++){
        for(int j = 1; j <= i; j++){
            fos.write((j + "*" + i + "=" + (j * i) + "\t" ).getByetes());
        }
        for.write("\r\n".getBytes());
    }
    
    fos.close();
  1. 输入任意目录,分别统计这个文件目录下文件和文件夹的个数
    @Test
    public void test1(){
        String path = "E:\\train\\jgs1904\\测试文件夹"
        getCount(path);
        System.out.println(fileCount);
        System.out.println(folderCount);
    }
    
    //定义两个全局的变量,用来递归记录值
    private static int fileCount = 0;
    private statiac int folderCount = 0;
    
    //递归用来记录值
    public static void getCount(String path){
        
        File file = new File(path);
        
        //获取当前目录下的所有文件和目录
        String[] list = file.list();
        
        for(String str : list){
            File itemFile = new File(path + "\\" + str);
            if (itemFile.isDirectory()){
                folderCount++;
                getCount(path + "\\" + str);
            } else {
                fileCount++;
            }
        }
    }
  1. 统计一个java文件有多少行代码
    String filePath = "./src/org/jgs1904/work/Work01.java";
    
    BufferedReader br = new BufferedReader(new FileReader(filePath));
    
    String line = null;
    int lineCount = 0;
    
    while((line = br.readLine()) != null){
        if(line.trim().equals("") || line.trim().startsWith("/*") || line.trim().startsWith("//") || line.trim().startsWith("*")){
            continue;
        }
        lineCount++;
    }
    br.close();
    
    System.out.println(lineCount);
  1. 判断一个字符文件中指定字符出现的次数,以及出现的具体位置(第几行第几个字符开始)
    String filePath = "Work02.txt";
    String str = "阿文";
    
    BufferedReader br = new BufferedReader(new FileReader(filePath));
    
    String line = null;
    int lineCount = 0;
    int count = 0;
    while((line = br.readLine()) != null){
        lineCount++;
        int index = -str.length();//以后循环是会加上字符串的长度,所以第一次循环是提前减去字符串的长度
        while((index = line.indexOf(str, index + str.length())) > -1){
            System.out.println(lineCount + "::" + index);
        }
    }
    
    br.close();
    
    System.out.println(count);
  1. 读取一个字符文件,将字符文件中的敏感词汇替换为*号,并重新输出成新的字符文件。敏感词汇列表在keywords.txt中编写,多个词汇使用逗号分隔。
    //读取敏感词的文件
    BufferedReader br = new BufferedReader(new FileReader("keywords.txt"));
    //敏感词中的内容默认不换行
    String keywordsStr = br.readLine();
    //以逗号分隔每个敏感词返回一个敏感词的String数组
    String[] keywords = keywordsStr.split(",");
    br.close();
    br = new BufferedReader(new FileReader("work03.txt"));
    
    BufferedWriter bw = new BufferedWriter(new FileWriter("work03_copy.txt"));
    
    String line = null;
    while((line = br.readLine()) != null){
        for (String keyword : keywords){
            char[] charArray = new char[keyword.length()];
            Arrays.fill(charArray, '*');
            line = line.replace(keyword, new String(charArray));
        }
        System.out.println(line);
        br.white(line);
        bw.newLine();
        
    }
    
    bw.close();
    br.close();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

JeffHan^_^

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

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

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

打赏作者

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

抵扣说明:

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

余额充值