IO流练习(修改文件中的数据)

case1:

java 复制代码
package com.lkbhua.IO.Test;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class test3 {
    public static void main(String[] args) throws IOException {
        /*
            文本文件中有以下数据:
               2-1-9-4-7-8
            将文件中的数据进行排序,变成以下的数据:
               1-2-4-7-8-9
        */

        // 1、读取文件中的数据
        // Alt + 回车
        FileReader fr = new FileReader(new File("lkb04-File&IOCode\\a.txt"));
        // 把每一个数据存储到一个StringBuilder中
        StringBuilder sb = new StringBuilder();
        int ch;
        while ((ch = fr.read()) != -1) {
            sb.append((char) ch);
        }
        fr.close();
        //System.out.println(sb);
        // 2、排序
        String str = sb.toString();
        String[] arrStr = str.split("-");
        ArrayList<Integer> list = new ArrayList<>();
        for (String s : arrStr) {
            int i = Integer.parseInt(s);
            list.add(i);
        }
        //System.out.println(list);
        Collections.sort(list);
        //System.out.println(list);
        // 3、写出
        FileWriter fw = new FileWriter(new File("lkb04-File&IOCode\\c.txt"));
        for (int i = 0; i < list.size(); i++){
            if (i == list.size() - 1){
                fw.write(list.get(i) + "");
            }
            else{
                fw.write(list.get(i) + "-");
            }
        }
        fw.close();
        System.out.println("完毕");
    }
}

🧩一**、为什么用 ArrayList?(核心问题!)**

因为字符串不能直接排序,得先变成数字!

想象一下:

  • 你手里有 6张卡片 ,上面写着 219478(全是文字,不是数字!)
  • 你想按大小排好,但 文字不能比大小("10" 比 "2" 大,但文字顺序 "1" 在 "2" 前)

👉 所以必须:

  1. 把文字 → 转成数字"2" → 2
  2. 把数字 → 放进一个可扩容的盒子ArrayList
  3. 自动排序的魔法Collections.sort()

为什么不用数组?

  • 数组大小固定,你不知道有多少数字(可能1个,可能100个)
  • ArrayList魔法盒子:你放多少数字,它就自动变多大!

💡 生活类比

你用 可伸缩的收纳盒 装玩具,比用固定大小的盒子(数组)方便多了!

🔁 二**、循环怎么执行的?(重点!)**

第一步:读文件 → 拼成字符串
java 复制代码
while ((ch = fr.read()) != -1) {
    sb.append((char) ch); // 把每个字节转成字符,塞进StringBuilder
}
  • 像用小扫帚扫地
    fr.read() 从文件开头一个字节一个字节扫 → ch 是当前字节(比如 50 代表 2
    sb.append((char) ch) → 把 50 转成 2,塞进 StringBuilder(高效拼接!)
  • 执行过程
    22-2-12-1-9 → ... → 2-1-9-4-7-8
    直到扫到文件末尾(-1),循环结束!
第二步:分割字符串 → 转数字
java 复制代码
String[] arrStr = str.split("-"); // "2-1-9" → ["2", "1", "9"]
for (String s : arrStr) {
    int i = Integer.parseInt(s); // "2" → 2
    list.add(i); // 把2放进ArrayList
}
  • 像分珠子
    split("-") 把字符串按 - 切开 → 得到 ["2", "1", "9"]
    for 循环:遍历每个小珠子 → Integer.parseInt 把珠子上的文字转成数字
  • 执行过程
    s="2"i=2list=[2]
    s="1"i=1list=[2,1]
    s="9"i=9list=[2,1,9]
    ...(最后 list=[2,1,9,4,7,8]
第三步:排序
复制代码
Collections.sort(list); // 把list变成 [1,2,4,7,8,9]
  • 像用自动排序书架
    Collections.sort() 会把 list 里所有数字 从小到大排好 ,不用你写排序算法!
    结果:[1,2,4,7,8,9]
第四步:写回文件
java 复制代码
for (int i = 0; i < list.size(); i++) {
    if (i == list.size() - 1) {
        fw.write(list.get(i) + ""); // 最后一个不加"-"
    } else {
        fw.write(list.get(i) + "-"); // 其他加"-"
    }
}
  • 像排版写作业
    i 是当前第几个数字,list.size()-1 是最后一个位置
    逻辑
    • i=01 → 写 1-
    • i=12 → 写 2-
    • ...
    • i=5(最后)→ 9 → 写 9(不加-
  • 最终输出1-2-4-7-8-9

case2:

java 复制代码
package com.lkbhua.IO.Test;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class test4 {
    public static void main(String[] args) throws IOException {
        /*
            文本文件中有以下数据:
               2-1-9-4-7-8
            将文件中的数据进行排序,变成以下的数据:
               1-2-4-7-8-9
        */

        // 1、读取文件中的数据
        // Alt + 回车
        FileReader fr = new FileReader(new File("lkb04-File&IOCode\\a.txt"));
        // 把每一个数据存储到一个StringBuilder中
        StringBuilder sb = new StringBuilder();
        int ch;
        while ((ch = fr.read()) != -1) {
            sb.append((char) ch);
        }
        fr.close();
        //System.out.println(sb);
        // 2、排序
        Integer[] arr = Arrays.stream(sb.toString()
                .split("-"))
                .map(Integer::parseInt)
                .sorted()
                .toArray(Integer[]::new);
        // 3、写出
        FileWriter fw = new FileWriter(new File("lkb04-File&IOCode\\c.txt"));
        String s = Arrays.toString(arr).replace(",", "-");
        String result = s.substring(1, s.length() - 1);
        fw.write( result);
        fw.close();
    }
}

🧩 一、为什么用Stream API?(比ArrayList更酷!)

因为Stream是Java 8的"魔法流水线",能一气呵成完成多个操作!

想象一下:

  • 你有一条自动分拣流水线(Stream)
  • 你把乱糟糟的字符串("2-1-9")扔进去
  • 流水线自动完成:
    文字→数字 (map)
    排序 (sorted)
    装箱(toArray)
  • 最后直接得到排好序的数字数组!

二、为什么比test3好?

  • test3:要写循环 + ArrayList + Collections.sort
  • test4:一行代码搞定所有步骤(Stream API)

💡 生活类比

你以前要自己:

  1. 拿起卡片 → 2. 转成数字 → 3. 放进盒子 → 4. 按大小排好
    现在用自动流水线
  2. 把卡片扔进入口 → 2. 机器自动完成所有步骤 → 3. 从出口拿排序好的卡片

🔁 三、Stream怎么执行的?(重点!)

java 复制代码
Integer[] arr = Arrays.stream(sb.toString().split("-"))
        .map(Integer::parseInt)
        .sorted()
        .toArray(Integer[]::new);
Step 1: sb.toString().split("-")
  • 输入"2-1-9-4-7-8"
  • 操作 :按-分割 → ["2", "1", "9", "4", "7", "8"]
  • 生活类比 :像把一串珍珠项链 ("2-1-9")拆成单颗珍珠
Step 2: .map(Integer::parseInt)
  • 操作 :把每颗珍珠(字符串)转成数字
    • "2" → 2"1" → 1"9" → 9...
  • 生活类比珍珠自动变钻石 (文字→数字) 💡 Integer::parseInt 是Java的快捷写法 ,相当于 s -> Integer.parseInt(s)
Step 3: .sorted()
  • 操作自动按大小排序
    • [2,1,9,4,7,8] → [1,2,4,7,8,9]
  • 生活类比钻石自动按大小排列(像智能珠宝架!)
Step 4: .toArray(Integer[]::new)
  • 操作 :把排序好的钻石装进数组盒子
  • 生活类比把排序好的钻石装进透明盒子Integer[] arr

整个Stream执行过程
["2","1","9"]流水线[2,1,9]排序[1,2,9]装盒[1,2,9]

🌟 四、写出部分为什么这么写?(避免多出逗号和方括号)

java 复制代码
String s = Arrays.toString(arr).replace(",", "-");
String result = s.substring(1, s.length() - 1);
fw.write(result);
问题

Arrays.toString(arr) 会输出 [1,2,4,7,8,9]

但我们需要 1-2-4-7-8-9不能有方括号和逗号!

解决方案
  1. .replace(",", "-")

    • "," 换成 "-"[1-2-4-7-8-9]
    • 就像把"逗号"改成"横杠"
  2. .substring(1, s.length() - 1)

    • s = "[1-2-4-7-8-9]"
    • substring(1, s.length()-1)
      • 从第2个字符开始(1位置)
      • 到倒数第2个字符结束(9位置)
    • 就像把"方括号"剪掉
    • 结果1-2-4-7-8-9

什么是bom头

🤔 一、BOM头到底是什么?

BOM头(Byte Order Mark) 就是文件开头的隐形小字符,像一个"编码身份证",告诉电脑:"我这个文件是UTF-8编码的哦!"

  • 它长啥样?

    在UTF-8文件中,BOM头是 EF BB BF(十六进制),也就是三个看不见的字符。

    • 用代码表示:"\xEF\xBB\xBF"
    • 用生活语言说:就像你给文件贴了个"UTF-8"的小标签
  • 为什么会有它?

    Windows记事本保存UTF-8文件时,自动给文件加了这个小标签(它以为这样能帮电脑更好识别编码)。

💡 举个栗子

你把"你好"写在纸上,记事本偷偷加了个"UTF-8"小标签在开头,结果你发给朋友,朋友看到"UTF-8你好",以为"UTF-8"是内容的一部分!

二、BOM头为什么是个"麻烦精"?

BOM头在普通文本文件中没问题 ,但在PHP文件中是个大麻烦!原因有:

  1. PHP不认这个标签

    PHP会把BOM头当作文件内容,而不是标签。比如:

    复制代码

    Php

    编辑

    复制代码
    1<?php
    2echo "Hello"; // 实际输出:BOM头 + "Hello"
    • 浏览器看到的是:Hello,但BOM头已经发送了HTTP头
  2. 导致"headers already sent"错误

    这是PHP最常见的错误之一!

    "Headers already sent by (output started at /path/to/file.php:1)"

  3. 页面布局问题

    即使设置了top: 0,页面也不会紧贴浏览器顶部,因为BOM头占了位置。

💡 生活类比

就像你给朋友写信,信封上写了"UTF-8",但信纸开头也写了"UTF-8",朋友收到信,以为"UTF-8"是信的内容,而不是信封信息。

IDEA如何关闭bom头

相关推荐
老华带你飞6 小时前
汽车销售|汽车报价|基于Java汽车销售系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端·汽车
西岭千秋雪_7 小时前
MySQL集群搭建
java·数据库·分布式·mysql
小马爱打代码7 小时前
Spring AI:文生视频 - wanx2.1-i2v-plus
java·人工智能·spring
华仔啊7 小时前
RebbitMQ 入门教程看这一篇就够了
java·后端·rabbitmq
象象翔7 小时前
AI+若依(实战篇)
java·人工智能·spring boot·spring
CHANG_THE_WORLD7 小时前
C++ vs Python 参数传递方式对比
java·c++·python
talenteddriver7 小时前
java: 4种API 参数传递方式
java·开发语言
四谎真好看7 小时前
Java 黑马程序员学习笔记(进阶篇31)
java·笔记·学习·学习笔记
sdkingz7 小时前
cursor学习笔记
java