使用Java读取CSV文件
开始话题
“最近太热了…”
尽管我想在家学习,但(我的母亲)总是会说:“省电啊!浪费电费!”所以我只能满头大汗地像个乡下人一样学习,作为一个软件工程师。
今天我想结合准备考Java Gold证书的学习,尝试一下“从CSV文件中读取数据并输出到控制台”的操作。我们将使用气象厅的过去气象数据。从获取数据部分开始一起来试试吧!
##1 ①「我要在气象厅的网站上获取数据!」
请首先点击下面的链接进入气象厅的网站。
当您在此界面上选择您喜欢的条件并点击“下载CSV文件”按钮后,您就可以下载CSV文件。
这次我进行了以下设置:
选取了以下地点:
– 名古屋市,爱知县
– 岡崎市,爱知县
选择以下项目之一:
– 日均气温
– 日最高气温
– 日最低气温
– 日降水量的总和
选择时间段
显示从2023年4月16日到2023年7月16日的每日数值
请选择选项〇。
对于需要注意处理的数据,请不要显示(存储)值。
对于在观测环境等变化之前后导致数据不均匀的处理,请不要显示(存储)变化之前的值。
由于这次只想要处理CSV文件的读写,所以我希望不显示任何显示选项,并且从一开始就减少多余的列。
确认已下载的文件
第一行是下载日期,
第三行是地点信息,
第四行是各列的名称,
从第七行开始存储着数据。
暂且尝试直接读取并输出,看看是否可行。
使用java.util.Scanner类似乎能够轻松地使用字符输入流。
//Mainクラス
public class Main {
public static void main(String[] args) throws Exception {
//ファイルから読み込むFIleInputStreamのインスタンスを作り、それをScannerクラスに渡す
FileInputStream fis = new FileInputStream("C:\\Users\\user\\Documents\\study\\data.csv");
Scanner scanner = new Scanner(fis);
try (scanner) {
while (scanner.hasNext()) { //次に読み込むべき行があるか判定
System.out.println(scanner.next()); //nextメソッドで1行ずつ読み込んでコンソールに出力
}
}
}
}
也许有些人会产生以下的疑问。(作者就是其中之一…笑)
疑问1:直接在Scanner类中传入文件路径不行吗?
→ Scanner类只是一个简化了文字输入流的工具。
就算你直接在Scanner类中传入文件路径字符串,它也只会将文件路径作为一行文字输出到控制台,然后结束(笑)。
真正从文件中读取文字的是FileInputStream哦!
为什么加了try文?
→是不是那个”try-with-resources”啊。
在Java中,当程序与外部进行连接时,似乎需要关闭(释放)该对象(连接)。
通常情况下,我们会使用try-catch-finally,在finally中编写close方法,
但是”try-with-resources”会在try块结束时自动关闭在try块中使用的对象,
所以似乎不需要在finally语句中额外编写。
「有疑问就代表有所学!」
「还不错嘛..(PekoPa)」
让我们将时间倒回,来确认执行结果吧!
哦!输出了!…但是为什么出现乱码呢?
所以接下来我想要解决乱码的问题。
我要指定字符编码!
ANSI是什么意思?
总的来说,看起来是以下的情况。
ANSI 是一种称为 Shift-JIS 的字符编码方式。ANSI 只支持 JIS0208 字符集合作为字符集合。因此,如果输入不是 JIS0208 的字符并且以 ANSI 格式保存,会出现乱码。
参考:http://office-qa.com/win/win309.htm#:~:text=ANSI是Shift-JISという、日常的に使われる文字化けを起こします。
参考链接:http://office-qa.com/win/win309.htm#:~:text=ANSI是Shift-JIS,会导致常见的乱码问题。
如果指定使用 Shift-JIS 进行读取,就可以了吧?
尝试指定文字编码进行读取
指定文字编码进行读取的步骤是。
-
- 实例化FileInputStream并读取csv文件
-
- 将其传递给InputStreamReader并以”Shift-JIS”进行读取
- 然后将其传递给BufferedReader
public class Main {
public static void main(String[] args) throws Exception {
//csvファイルを読み込む
FileInputStream fis = new FileInputStream("C:\\Users\\user\\Documents\\study\\data.csv");
try {
//Shit-JISで読み込む
BufferedReader b_reader = new BufferedReader(new InputStreamReader(fis, "Shift-JIS"));
try (Scanner scanner = new Scanner(b_reader)) {
while (scanner.hasNext()) { //次に読み込むべき行があるか判定
System.out.println(scanner.next()); //nextメソッドで1行ずつ読み込んでコンソールに出力
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
“好的好的,我懂了!为什么要”3.进一步传给BufferedReader”呢?”
由于这个问题可能会陷入深入研究的泥沼中,所以省略掉,但通过这样做似乎可以提高处理速度。
可能会对想要了解更多的人有所参考价值的网站是 https://rainbow-engine.com/compare-inputstream-bufferedreader/。
让时间倒流吧!(ぺこぱ)
Java Gold的资格考试范围就是以上内容。
尝试获取最高和最低气温吧!
「什么时候会只需要把CSV文件输出到屏幕上呢…」
根据目前的知识,我试着创建了一个能够获取最高温度并在控制台输出的程序!下次发布计划。