使用Java读取CSV文件

开始话题

“最近太热了…”

尽管我想在家学习,但(我的母亲)总是会说:“省电啊!浪费电费!”所以我只能满头大汗地像个乡下人一样学习,作为一个软件工程师。

今天我想结合准备考Java Gold证书的学习,尝试一下“从CSV文件中读取数据并输出到控制台”的操作。我们将使用气象厅的过去气象数据。从获取数据部分开始一起来试试吧!

##1 ①「我要在气象厅的网站上获取数据!」

请首先点击下面的链接进入气象厅的网站。

 

image.png

当您在此界面上选择您喜欢的条件并点击“下载CSV文件”按钮后,您就可以下载CSV文件。

这次我进行了以下设置:
选取了以下地点:
– 名古屋市,爱知县
– 岡崎市,爱知县

选择以下项目之一:
– 日均气温
– 日最高气温
– 日最低气温
– 日降水量的总和

选择时间段
显示从2023年4月16日到2023年7月16日的每日数值

请选择选项〇。
对于需要注意处理的数据,请不要显示(存储)值。
对于在观测环境等变化之前后导致数据不均匀的处理,请不要显示(存储)变化之前的值。

由于这次只想要处理CSV文件的读写,所以我希望不显示任何显示选项,并且从一开始就减少多余的列。

确认已下载的文件

image.png
image.png

第一行是下载日期,
第三行是地点信息,
第四行是各列的名称,
从第七行开始存储着数据。

暂且尝试直接读取并输出,看看是否可行。

使用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)」

让我们将时间倒回,来确认执行结果吧!

image.png

哦!输出了!…但是为什么出现乱码呢?

所以接下来我想要解决乱码的问题。

我要指定字符编码!

image.png

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 进行读取,就可以了吧?

尝试指定文字编码进行读取

指定文字编码进行读取的步骤是。

    1. 实例化FileInputStream并读取csv文件

 

    1. 将其传递给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/。

让时间倒流吧!(ぺこぱ)

image.png

Java Gold的资格考试范围就是以上内容。

尝试获取最高和最低气温吧!

「什么时候会只需要把CSV文件输出到屏幕上呢…」

根据目前的知识,我试着创建了一个能够获取最高温度并在控制台输出的程序!下次发布计划。

广告
将在 10 秒后关闭
bannerAds