IO(普通文件的内容读取)------javaEE

普通文件可能是二进制文件可能是文本文件

输入:流式,水箱代表文件,流出来的水是数据。


1.InputStream(抽象类)(输入部分)

有俩个接口Closeable,Autocloseable可以关闭,就是把水龙头打开或者关闭

 常用的方法:

abstract int read()  //EOS,当值为1时说明流的最终端被读走了,也就是,文件里什么都没了。 一次一滴

int read(byte[] b)   //一次一桶,byte[]b就是准备好的水桶(在内存中开辟好一块空间,从输入设备中把数据读到我内存的这个空间)

int read(byte[] b,int off,int len)   //倒数俩个返回值<=b.length, -1才代表数据全部读完了,0不代表

接口的实现类

FileInputStream   //从文件中往出读

SocketInputStream  //从Socket往出读

这几行一共13个字节/r/n在第一行隐藏,意思是,回车

再回车一次,加俩个15个字节

 代码示例

1.1文件读取的方法

 当前是在io下

这里是相对路径,可以直接写hello.txt或者上面的这种,都是可以的

上面的一行,也可以写为

File file =new File("hello.txt);

FileInputStream is2 =new FeilInputStream(file);


一般写图片里面的就可以

然后我们知道文件有13个字节的数组,我们就用is.read(数组)


默认抛出的异常,是FileNotFoundException,路径/文件不存在


 

 文件中49就是1的unicode编码

13 /r

10 /n

hello 就是 72 101 108 108 111


 文件都被读完了,再读就是-1;

数组被改为10了之后,前面的按桶读,会变成10个字节,剩下llo没读

再读一次是按滴读的,就是读 l 也就是108


写成这样就不用写close了,会自动给我关掉 


不知道数据源有多少数据的情况下,怎么确保把所有数据全部读完?

就是从里面读出来-1就代表结束掉了

可以写为

while(true){

int b =is.read();

if(b==-1){

break;

   }

//加工b数据

}


用is.read(byte[] b)效果一样,下面会打印俩次,第一次10个,第二次3个

写为5,就是读三次。一般来说,读硬盘的频次越少越好,所以,容量写大一点(空间换时间)

 一般为1024,或者1024的倍数,读一次即可

换中文读取:

 原理上下面是4个字节,但是实际是12个字节

原因:UTF-8变长编码,意思是每个字符占用的字节长度是不相等的

数字、英文占1个字节

中文绝大多数占三个字节

emoji占4个字节,就是平常用的小表情

 


但是把这些查出来的数字还得自己查表对应出来,

用JDK直接得到查表得四个字

我们用的System.in就是InputStream类型

所以说,我们的new Scanner(InputStream类型 is,"utf-8")只要传入这个类型并把我们知道的字符集编码传入即可(我们平常看到的乱码就是以为的字符集和原本的字符集对不上) 

而我们可以不改GBK,实现不乱码,就是把文件的utf-8改为GBK

1.2输入部分的其他一些 

 Reader类

Reader 地位和InputStream类似,做的是字符的处理

BufferedReader

reader.readLine()   =  scanner.nextLine();


2.OutputStream

最常见的实现类:FileOutputStream //向某一个文件中输入

2.1让中文写入正确

System.out 是PrintStream类型 

 

 练习,实现小程序

1.文本替换工具,“你好”(文件1)->“我好”(文件2)

思路:读、换、写

 2.文件的复制(任意类型的文件都可以)一颗树的节点的复制

思路:IntputStream+OutputStream

也可以通过这个实现简单的文件夹的复制。

3.文件夹的复制(一颗树的复制)

思路:遍历文件夹中的每一个节点  

 第一行我要复制的目录的完整绝对路径

第二行源的开始复制的位置

第三行目标的开始复制的位置

所以相对路径就是目标开始位置+从绝对路径中截取源开始位置之后的目录

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

public class CopyDirectory {
    //源地址
    static String source = "D:\\课程\\2022-05-08-Java19-22班-线程总结";
    //目标地址
    static String dest = "D:\\课程\\2022-05-09-Java19班-IO\\目标";

    public static void main(String[] args) throws IOException {
        File srcFile = new File(source);
        //看源地址是不是目录
        if (!srcFile.isDirectory()) {
            System.out.println("源不是目录");
            return;
        }
        //看目标地址是否存在,如果存在则停止复制,防止把原来的目录删掉
        File destFile = new File(dest);
        if (destFile.exists()) {
            System.out.println("目标路径已经存在");
            return;
        }
        //递归复制的过程
        traversal(srcFile, destFile);
    }

    private static void traversal(File dir, File destFile) throws IOException {
       //得到dir下所有的文件
        File[] files = dir.listFiles();
        if (files == null) {
            return;
        }
        for (File file : files) {
            //如果文件是个目录
            if (file.isDirectory()) {
                //如何得到相对路径,本质上是在做字符串处理的工作
                String path1 = file.getCanonicalPath();
                //从源位置开始截取地址,
                String relative = path1.substring(source.length());
                String path2 = dest + relative;
                File file2 = new File(path2);
                file2.mkdirs();
                traversal(file, destFile);
            } else if (file.isFile()) {
            }
        }
    }
}

 剪切粘贴时间复杂度为O(1)

复制粘贴时间复杂度为O(n),因为有遍历的过程

课后代码:新建maven工程

字符图  像素->灰度->根据不同灰度替换

windows上面的换行\r\n

Linux上是\n

\r回到行首不换行 

\n回到下一行

没听懂

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值