IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【Debug】Java NIO 使用 channel 向文件写入内容失败? -> 正文阅读

[Java知识库]【Debug】Java NIO 使用 channel 向文件写入内容失败?

每当遇到一些莫名其妙的错误,怎么都排查不出来的时候,那个错误一定是个非常无脑的问题。

问题描述

在看 NIO 时,自己尝试了下它的 API;于是在资源目录下创建了 a.txtb.tztc.txt,but,在我尝试读取时并没有出现问题,但是在写入时一直有问题(写入后通过 idea 查看资源目录下的 txt 文件发现并没有写入(还是空文件)),并且得不到解决;以下是 “bug” 代码:

public class Test {
    public static void main(String[] args) throws IOException {
        // 准备缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(128);
        // 读取文件
        try (
                FileInputStream fis = new FileInputStream(getPath("io/a.txt"));
                FileChannel channel = fis.getChannel();
        ) {
            channel.read(buffer);
            buffer.flip();
            byte[] bytes = new byte[buffer.limit()];
            buffer.get(bytes);
            System.out.println(new String(bytes));
        } catch (Exception e) {
            e.printStackTrace();
        }

        buffer.clear();

        // 写入数据
        try (
                // 问题就出在这行代码了
                FileOutputStream fos = new FileOutputStream(getPath("io/b.txt"), false);
                FileChannel channel = fos.getChannel();
        ) {
            String data = "【" + System.currentTimeMillis() + "】 写入新数据";
            buffer.put(data.getBytes());
            buffer.flip();
            channel.write(buffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        buffer.clear();
    }

    public static String getPath(String fileName) {
        URL resource = NIO.class.getClassLoader().getResource(fileName);
        return resource != null ? resource.getPath() : "";
    }
}

发现问题

IDEA 中资源目录的磁盘路径实际上是:盘符://项目路径/项目名/src/main/resources/file

而实际上经过 IDEA 对项目 Build 后(编译.java 文件生成字节码,复制静态资源…)最终获取到的资源目录的实际路径是:盘符://项目路径/项目名/target/classes/file

在这次 bug 中就是为了图省事,懒得取 copy 文件的绝对路径,然后写了一个方法通过类加载器去获取资源文件夹的路径:

    public static String getPath(String fileName) {
        URL resource = NIO.class.getClassLoader().getResource(fileName);
        return resource != null ? resource.getPath() : "";
    }

两个路径在我的磁盘上的绝对路径如下:

  • D:\Users\Xbai-hang\Desktop\Code\Java\Java_Interview\target\classes\io\*.txt
  • D:\Users\Xbai-hang\Desktop\Code\Java\Java_Interview\src\main\resources\io\*.txt

实际上通过上面的方法获取到的实际路径是前者,而我通过 IDEA 查看的是后者路径下的文件,读取可能还看不出问题,写入更改文件就发现了维妮塔。

解决问题

  • 通过找到 target 文件夹下的 *.txt 文件发现确实是写入了,于是删除了这两个文件,运行 Test 类,发现文件并没有被复制到 target 文件夹下
  • resources/io 文件夹下创建一个 d.txt 再次运行,发现 target 文件夹下只有 d.txt,而没有 a.txtb.txtc.txt
  • Rebuild ProjectBuild Project 后发现仍然没有用。
  • 删除 target 文件夹后重新 Build 项目有用。
  • 更改 d.txt 文件后运行 Test 类,target 文件夹下的文件会跟着更改。
  • 通过 mvn clean 后重新运行有效(其实就是删除了 target 文件夹)。

对于 IDEA 中的 target 文件夹的更新逻辑暂时没有搞清楚,留个坑,后面补,目前逻辑如下:

  • 在已有 target 文件夹的情况下(均指运行一次 Test 类后的情况)
    1. 手动删除其内文件后不会再次更新过去
    2. resources 目录下新创建的文件会更新过去
    3. 删除 resources 目录下的文件,target 文件夹下的文件也会对应删除
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 18:51:47  更:2022-06-29 18:55:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/26 15:11:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码