javaSE————文件IO(2)、

javaSE————文件IO(2)、

文件内容的读写——数据流

我们对于文件操作使用流对象Stream来操作,什么是流对象呢,水流是什么样的,想象一下,水流的流量是多种的,可以流100ml,也可以流1ml,流对象就和水流很像,我们可以一次读取100个字节,或者一次读取1个字节;

1,字节流

1)inputStream

先来使用inputStream,这个是字节流的输入,inputStream是抽象类,和下面的outputStream是一样的,我们需要FileInputStream来实例化对象,FileInputStream的构造方法:

签名说明
FileInputStream(File file1)可以使用file构造文件输入流
FileInputStream(String str)也可以使用文件路径构造输入流

那么inputStream有啥方法呢:

返回类型签名说明
int read()一次就读一个字节,读完了返回-1
intread(byte[] byte)一次读字节数组这么长的数据,返回-1就说明读完了
intread(byte[] byte,int start,int len)一次读取start到len的数据,读完了返回-1
voidclose()关闭输入流

用代码展示输入流:我们这里注意使用这些方法会抛异常,

InputStream inputStream = null; try { inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识点/Demo/QQ截图20240915161600.png"); } catch (FileNotFoundException e) { throw new RuntimeException(e); } finally { inputStream.close(); }

这里推荐使用try-with-resources,可以自动去close,为啥我们一定要去close呀,之间学数据结构都不用像c一样嗷嗷释放,因为文件操作不属于内存管理,GC垃圾回收不管他,我们嘚自己去关闭,不关闭他有什么影响呢,还记得进程中PCB中的文件描述符表吗,我们每打开一个程序就会在文件描述符表上自动创建一个固定长度的顺序表,就会申请一个表项,这个不会去扩容的,一直申请,不关闭,表项就没了;

 } try (InputStream inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识" + "点/Demo/QQ截图20240915161600.png")){ while (true){ int a = inputStream.read(); if(a==-1){ break; } System.out.println(a); } }

 我们在try中实例对象就相当于打卡了这个文件,如果FileInputStream爆红了,就说明文件不存在了,代码是一次只读取一个字符的情况,读到数据的时候,就会把读到的字符返回给a,因为是字节,所以会返回0-255的数值,在试试一次读取多个字节:

try (InputStream inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识" + "点/Demo/QQ截图20240915161600.png")){ while (true){ byte[] bytes = new byte[20]; int a = inputStream.read(bytes); if(a==-1){ break; } for (int i = 0; i < 20; i++) { System.out.print(bytes[i]+" "); } System.out.println(); } }

我们创建一个字节数组,每次读取固定byte.length长度的字符,再输出,看看结果

 此外呢,我们还可以通过Scanner来读取,我们在网络编程TCP协议中常常使用Scanner来代替intputStream,但是这里不太行,因为,Scanner会根据inputStreamReader把字节流转化为字符流,我们传的是一个图片,图片是二进制指令,我们需要遵守他们字节的编码方法,我们现在重新弄一个路径,试试读取字符;

我们在test中写3个哈哈哈;

InputStream inputStream = new FileInputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt"); Scanner scanner = new Scanner(inputStream); while (scanner.hasNext()){ String a = scanner.next(); System.out.print(a+" "); }

 

2)outputStream

outputStream就是字节流的输出了,同样也是一个抽象类,需要FileOutputStream来辅助实例对象,FileOutputStream的构造方法是和FileIntputStream一样的,我们来看看OutputStream的的方法:

返回值签名说明
voidwrite(int b)写入所给的字节数据
voidwrite(byte[] b)写入长度为b.length的字节数据
int write(byte[] b,int set,int len)将字节数组从Set开始,写入len个长度
voidclose()关闭字节流
voidflush()

这里的flush我们拿出来单独说,这个是什么方法呢,我们文件IO操作的数据是很慢的,我们不可能去等这个操作,一个一个的把这些数据写入到设备中,所以我们会先把数据攒到缓冲区中,等到缓冲区满了之后我们再把这些数据一起写入设备,所以我们可以使用这个操作,来冲刷缓冲区,不等他满了,直接把数据写入设备;

还是使用代码来看看:

try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt")){ outputStream.write(97); outputStream.write(98); outputStream.write(98); } catch (IOException e) { throw new RuntimeException(e); }

我们写入几个字符,应该是abb;

test文档中出现了abb,哎不对呀,我们之前不是在这写了哈哈哈三个字吗,哪去了,我们的write操作是会覆盖之前的内容的,如果想要接着写我们要使用追加模式

 try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt" ,true)){ outputStream.write(76); } catch (IOException e) { throw new RuntimeException(e); }

实例化的构造方法中写true,就可以追加的写了;

这里多了一个l,再试试多行的写入

try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test.txt" ,true)){ byte[] bytes = new byte[]{99,98,97,96,95}; outputStream.write(bytes); } catch (IOException e) { throw new RuntimeException(e); }

我们还可以试试,如果我们没有这个test文件会怎么样呢,怎么去写入呢,

 try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){ byte[] bytes = new byte[]{99,98,97,96,95}; outputStream.write(bytes); } catch (IOException e) { throw new RuntimeException(e); } 

我们写不存在的test4;

它自己创建了对应的文件并且写入了数据;

读数据有Scanner,那么写有没有对应的呢?有的兄弟有的,像这样的‘’‘’‘’‘’哈哈,不开玩笑了,我们还可以使用PrintWriter,来上代码:

try (OutputStream outputStream = new FileOutputStream("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){ PrintWriter printWriter = new PrintWriter(outputStream); printWriter.print(98); printWriter.println(99); printWriter.flush(); } catch (IOException e) { throw new RuntimeException(e); }

 

也是可以的;


2,字符流

我们使用字节流读取二进制数据,我们为啥还要字符流呢,通过编码方式,直接得到一堆字符不香吗;

1)Reader

我们使用Reader读数据,

public static void main(String[] args) { try(Reader reader = new FileReader("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){ while (true){ char[] chars = new char[1024]; int b = reader.read(chars); if(b==-1){ break; } for (int i = 0; i < b; i++) { System.out.print(chars[i]); } } } catch (IOException e) { throw new RuntimeException(e); } }

这就是我往test中放的,我们要注意java的编码和idea的编码方式,我这里的都是utf-8,如果不同的话是识别不出来的;

2)Writer

我们使用Writer来写入数据:

try(Writer writer = new FileWriter("C:/cctalk/java代码容易犯错的知识点/Demo/test4.txt")){ char[] chars = new char[]{'H','E','l','l','o'}; writer.write(chars); } catch (IOException e) { throw new RuntimeException(e); }

2,练习

我们来几个小练习

1)扫描指定⽬录,并找到名称中包含指定字符的所有普通⽂件(不包含⽬录),并且后续询问⽤⼾是否 要删除该⽂件

 public class Demo2 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入要找的目录"); String rootDir = scanner.next(); File file = new File(rootDir); if(!file.isDirectory()){ System.out.println("这不是个目录"); return; } System.out.println("请输入要删除的关键字"); String key = scanner.next(); find(file,key); } public static void find(File rootDir,String key){ File[] files = rootDir.listFiles(); if(files==null){ return; } for (File file:files){ System.out.println("正在遍历"+file.getAbsoluteFile()); if(file.isFile()){ dealFile(file,key); }else { find(file,key); } } } public static void dealFile(File file,String key){ if(file.getName().contains(key)){ System.out.println("发现文件,是否要删除呢,删除输入y"); Scanner scanner = new Scanner(System.in); String s = scanner.next(); if (s.equals("y")){ file.delete(); }else { return; } }else { return; } } } 

代码实现,我们现在藏几个文件:

"C:\cctalk\java代码容易犯错的知识点\Demo\demo2\新建文件夹\test4.txt" 

看看他能不能把5个带关键字的都找到,

成功找到了;

2)进行普通文件的复制

"C:\cctalk\java代码容易犯错的知识点\Demo\test4.txt"

"C:\cctalk\java代码容易犯错的知识点\Demo\test1.txt"

我们把后面的文件复制到这个新建文件夹中;

public class Demo3 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入源文件路径"); String src = scanner.next(); File file = new File(src); if (!file.isFile()){ System.out.println("输入的不是源文件路径或者源文件不存咋"); return; } System.out.println("请输入目标文件路径"); String destPath = scanner.next(); File file1 = new File(destPath); if(!file1.getParentFile().isDirectory()){ System.out.println("输入的目标文件路径的父目录不存在"); return; } System.out.println(file.getAbsoluteFile()); System.out.println(file1.getAbsoluteFile()); try (InputStream inputStream = new FileInputStream(file); OutputStream outputStream =new FileOutputStream(file1)){ while (true){ byte[] bytes = new byte[1024]; int a = inputStream.read(bytes); if(a==-1){ break; } outputStream.write(bytes,0,a); } } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } }

我们就能看到

text1的数据复制到test4上了;

3)扫描指定内容并找到名称或者内容包含指定字符的文件;

C:\cctalk\java代码容易犯错的知识点

"C:\cctalk\java代码容易犯错的知识点\Demo\demo2\demo3\java.txt"

"C:\cctalk\java代码容易犯错的知识点\Demo\demo2\demo3\demo4\214.txt"

我们在第一个目录中找后面两个,第三个的内容包含java关键字的:

public class Demo4 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入要搜索的内容,输入目录"); String src = scanner.next(); File file = new File(src); if(!file.isDirectory()){ System.out.println("输入的不是目录"); return; } System.out.println("请输入关键字"); String key = scanner.next(); find(file,key); } public static void find(File file,String key){ File[] files = file.listFiles(); if(file==null){ return; } for (File file1:files){ if (file1.isFile()){ dealFile(file1,key); }else { find(file1,key); } } } public static void dealFile(File file,String k){ if (file.getName().contains(k)){ System.out.println("文件名包含" + file.getName()); return; } StringBuffer stringBuffer = new StringBuffer(); try (Reader reader = new FileReader(file)){ while (true){ char[] chars = new char[1024]; int a = reader.read(chars); if (a==-1){ break; } stringBuffer.append(chars,0,a); } } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } if(stringBuffer.indexOf(k)>=0){ System.out.println("文件内容包含"+file.getName()); } } } 

OK啦

Read more

10分钟打造专属AI助手!ToDesk云电脑/顺网云/海马云操作DeepSeek哪家强?

10分钟打造专属AI助手!ToDesk云电脑/顺网云/海马云操作DeepSeek哪家强?

文章目录 * 一、引言 * 云计算平台概览 * ToDesk云电脑:随时随地用上高性能电脑 * 二 .云电脑初体验 * DeekSeek介绍 * 版本参数与特点 * 任务类型表现 * 1、ToDesk云电脑 * 2、顺网云电脑 * 3、海马云电脑 * 三、DeekSeek本地化实操和AIGC应用 * 1. ToDesk云电脑 * 2. 海马云电脑 * 3、顺网云电脑 * 四、结语 * 总结:云电脑如何选择? 一、引言 DeepSeek这些大模型让 AI 开发变得越来越有趣,但真要跑起来,可没那么简单! * 本地配置太麻烦:显卡不够、驱动难装、环境冲突,光是折腾这些就让人心态崩了。 * 云端性能参差不齐:选错云电脑,可能卡到爆、加载慢,还容易掉线,搞得效率直线下降。 * 成本难控:有的平台按小时计费,价格一会儿一个样,

By Ne0inhk
用 DeepSeek 打造你的超强代码助手

用 DeepSeek 打造你的超强代码助手

DeepSeek Engineer 是啥? 简单来说,DeepSeek Engineer 是一个基于命令行的智能助手。它能帮你完成这些事: * 快速读文件内容:比如你有个配置文件,直接用命令把它加载进助手,后续所有操作都可以基于这个文件。 * 自动改文件:它不仅能提建议,还可以直接生成差异表(diff),甚至自动应用修改。 * 智能代码生成:比如你让它生成代码片段,它会按照指定格式和规则直接返回。 更重要的是,这一切都是通过 DeepSeek 的强大 API 来实现的。想象一下,你有个贴身助手,不仅能听懂你的代码需求,还能直接动手帮你写! 核心功能拆解 我们先来看 DeepSeek Engineer 的几个核心能力,让你更好地理解它的强大之处。 1. 自动配置 DeepSeek 客户端 启动这个工具时,你只需要准备一个 .env 文件,里面写上你的 API Key,比如: DEEPSEEK_API_

By Ne0inhk
解锁DeepSeek潜能:Docker+Ollama打造本地大模型部署新范式

解锁DeepSeek潜能:Docker+Ollama打造本地大模型部署新范式

🐇明明跟你说过:个人主页 🏅个人专栏:《深度探秘:AI界的007》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、什么是Docker 2、什么是Ollama 二、准备工作 1、操作系统 2、镜像准备 三、安装 1、安装Docker 2、启动Ollama 3、拉取Deepseek大模型 4、启动Deepseek  一、引言 1、什么是Docker Docker:就像一个“打包好的App” 想象一下,你写了一个很棒的程序,在自己的电脑上运行得很好。但当你把它发给别人,可能会遇到各种问题: * “这个软件需要 Python 3.8,但我只有 Python 3.6!

By Ne0inhk
深挖 DeepSeek 隐藏玩法·智能炼金术2.0版本

深挖 DeepSeek 隐藏玩法·智能炼金术2.0版本

前引:屏幕前的你还在AI智能搜索框这样搜索吗?“这道题怎么写”“苹果为什么红”“怎么不被发现翘课” ,。看到此篇文章的小伙伴们!请准备好你的思维魔杖,开启【霍格沃茨模式】,看我如何更新秘密的【知识炼金术】,我们一起来解锁更加刺激的剧情!友情提醒:《《《前方高能》》》 目录 在哪使用DeepSeek 如何对提需求  隐藏玩法总结 几个高阶提示词 职场打工人 自媒体创作 电商实战 程序员开挂 非适用场地 “服务器繁忙”如何解决 (1)硅基流动平台 (2)Chatbox + API集成方案 (3)各大云平台 搭建个人知识库 前置准备 下载安装AnythingLLM 选择DeepSeek作为AI提供商 创作工作区 导入文档 编辑  编辑 小编寄语 ——————————————————————————————————————————— 在哪使用DeepSeek 我们解锁剧情前,肯定要知道在哪用DeepSeek!咯,为了照顾一些萌新朋友,它的下载方式我放在下面了,拿走不谢!  (1)

By Ne0inhk