前提・実現したいこと
javaの基礎学習をつい先日1周した者です。
実践的な何かを作りたく、タイトルのようなものを想定し現在作成中です。
作り方が分からなくなってしまい、長時間手が止まってしまったのでここに記述し、
他者にみてもらう事で整理をしようと思っております。
かなり迷走していて基礎も調べながらの記述になっているため
コードが読みづらいかもしれませんがご容赦ください。
・csvファイルはindex年月日時分秒のフォーマットを使い作成
・読み込みたいフォルダはエディターのデバック環境に引数として登録済み
・csvファイルには HTMLファイル名とタイトルを1行ずつ記述する
上記のようなものを目標に作成しております。
該当のソースコード
csvファイルの作成 htmlファイル名取得 htmlファイル名をcsvファイルに書き込み までの完成したコード import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.io.BufferedWriter; import java.io.FileWriter; public class App { public static void main(String[] args) throws Exception { // void型でmainを定義 Calendar c = Calendar.getInstance(); //カレンダークラスにより現在日時を取得 DateFormat myFormat = new SimpleDateFormat("_yyyy_MM_dd_HH_mm_ss"); // 日時のフォーマットを設定 String FileName = "index" + myFormat.format(c.getTime()); // FileNameにファイルネームを定義 File newFile = new File("/Users/mono/tmp/" + FileName + ".csv"); // Fileを/Users/mono/tmp/FileName.csvで作成 try{ if(newFile.createNewFile()){ // もしファイル作成できたら System.out.println(FileName + "のファイルの作成に成功"); // 上記の文章をコマンドラインに表示 }else{ // ファイル作成出来ていなかったら System.out.println("ファイルの作成に失敗"); // 上記の文章をコマンドラインに表示 } }catch(IOException e){ System.out.println(e); } if (args.length != 0){ // 引数の数が0+1個だったら File dir = new File(args[0]); // 引数に設定してあるフォルダをdirに定義 File[] fileList = dir.listFiles(); // fileListにフォルダ内のファイルを配列として格納 for(int i = 0; i < fileList.length; i++){ // fileListの数だけ処理を繰り返す if(fileList[i].getName().contains(".html")){ // .html拡張子のファイル名を取得 if(checkBeforewritefile(newFile)){ BufferedWriter bw = new BufferedWriter(new FileWriter(newFile)); // newFileにまとめて書き込む準備をバッファでする。 bw.write(fileList[i].getName()); // 処理中のfileListの名前をnewFileに書き込む bw.close(); // 1行の処理のため一度閉じる System.out.println(fileList[i].getName() + "のファイル名を書き込みました"); // 書き込めた場合この文章をコマンドラインに表示 } else{ System.out.println("書き込めませんでした"); } } } } } private static boolean checkBeforewritefile(File newFile) { if(newFile.exists()){ if(newFile.isFile() && newFile.canWrite()){ return true; } } return false; } }
作りたいものの作りかけのコード import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.io.Closeable; public class App { public static void main(String[] args) throws Exception { //カレンダークラスにより現在日時を取得 Calendar c = Calendar.getInstance(); // 日時のフォーマットを設定 DateFormat myFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss"); // ファイル名を定義 String FileName = "index" + myFormat.format(c.getTime()); // File newFile = new File("/Users/mono/tmp/" + FileName + ".csv"); try{ if(newFile.createNewFile()){ System.out.println(FileName + "のファイルの作成に成功"); }else{ System.out.println("ファイルの作成に失敗"); } }catch(IOException e){ System.out.println(e); } if (args.length != 0){ //引数必ず1つであること //エディターに引数設定済み File dir = new File(args[0]); //設定からフォルダを引数として受け取る File[] fileList = dir.listFiles(); //フォルダの中身を配列として格納 if(fileList != null){ //もしフォルダの中身が終わってないなら for(int i = 0; i < fileList.length; i++){ //繰り返し処理をします try{ if (fileList[i].getName().contains(".html")){//もし html を含むファイル名があるならば if (checkBeforewritefile(newFile)){ // もしcsvファイルに書き込みをするならば BufferedWriter bw = new BufferedWriter(new FileWriter(newFile)); // csvファイルにファイル書き込みをする宣言 // BufferedReader br = new BufferedReader(new FileReader(fileList[i])); // ファイルを読み込む準備 // String line; // String型を定義 // while((line = br.readLine()) != null); // 行がなくなるまで1行ずつ処理していく // String regex =" <(title)>.*?<\>"; // これを取得したいと定義 // Pattern p = Pattern.compile(regex); // 定義した物をパターンと定義 // check(p,line); // 1行ずつパターンがないかチェック System.out.println(fileList[i].getName() + "のファイル名を書き込みました"); bw.write(fileList[i].getName()); //フォルダから取得したhtmlを含むファイル名をcsvファイルに書き込み bw.close(); } }else{ System.out.println("書き込めませんでした"); } }catch(IOException e){ System.out.println(e); }finally{ } } } } } private static boolean checkBeforewritefile(File newFile) { if(newFile.exists()){ if(newFile.isFile() && newFile.canWrite()){ return true; } } return false; } private static void check(Pattern p, String line) { Matcher m = p.matcher(line); if (m.find()){ // バッファ 取得したタイトル で書き込み }else{ // バッファ タイトルなし で書き込み } } }
分かっていない事
・タイトルにマッチしている物を書き込む方法
・繰り返しの処理を何段階かに分けて書く方法
質問内容やコードが見づらく申し訳ございません。
ご指摘があった所を一つずつなおしていきますので何卒よろしくお願いします。
> HTMLファイルの中の要素を取得
というところで結構面倒(HTMLのパース。初心の方には難しい)です。その部分は後まわしでまずはファイル名のみ、などとしてみてはいかがでしょうか。ひとつひとつ理解、実装するのが大事です。
ありがとうございます!
ご指摘の通りだと思います。そのように部分的に進めて参りまして
1つにまとめようとした段階で混乱してしまってます...
ご提示のコードで全部ですか?せめてコンパイルが通る内容とした方が良いと思います。(importなど省いてますよね)
作りながら考えるから難しいのでは、と思います。
部分的に行ったものは
・csvファイルの作成
・フォルダ内のhtmlファイル名の取得
・指定のhtmlファイルの全文の取得
です。
繰り返しの処理と正規表現を用いれば出来ると思っていたので全部まとめてみた所、ご指摘の通りコンパイルが通らなくなってしまいました。
こちらのソースコードにimportを省いてしまっていたのは完全に私のミスです...すぐ修正いたします。
下手に自作するよりライブラリ使ったほうが良いでしょうね。正規表現もそうですし、「htmlとして正しく解釈できるか」とか多角的な視点とスキルが必要です。
m.ts10806さん
ご指摘ありがとうございます。基礎の知識を活かせるか。という自己学習の一貫だったため今回ライブラリは使用しないでやってみたいと思っています。フォルダ内のhtmlファイルのみを取得する事自体は部分的な実装で出来ていました。が仰るとおり正規表現には自信がないのが現状です。
正規表現以外の部分を形にするのは難しいでしょうか?
私が要件把握しきれてないだけかもしれませんが、「正規表現以外の部分」とは具体的にどこになりますか?
・csvファイルの作成
・フォルダ内のhtmlファイルのみを取得
・htmlファイル名をcsvファイルに記述
だけの物ですね。
2021/02/22 14:57のコメントからすると下記はやってみている、しかしコンパイル通らない、ということですね
・csvファイルの作成
・フォルダ内のhtmlファイルのみを取得
その機能単体では通っている形ですね...
失礼しました。先ほどの3点のみのコードは現時点で作成出来てしまいました。。
そこにタイトルのみの取得、書き込みのコードがあるからコンパイルできないみたいでした。
ちょっと迷走しているようですが、結局のところ今、問題にしているのはどこなのでしょう。「タイトルのみの取得、書き込みのコードがコンパイルできない」ですか? (そこを直したらまた別の問題が出る可能性はありますが)
dodox86 さん
そうです!迷走しておりましたがその部分だけが難しく、また他のコードと繋げるとエラーになってしまう形ですね
> その部分だけが難しく、また他のコードと繋げるとエラーになってしまう形ですね
別の部分について既に回答をいただいていますが、おおもとの問題としては色んな機能をひとつにしようとして混乱、迷走していることにあると
思います。HTMLファイルからタイトルを取り出すことに関して、「難しい」ということと「他のコードに繋げるとエラー」と言うのは別の問題です。
「難しい」部分に関しては<HEAD>~</HEAD>中の<TITLE>要素を取り出す、「他のコードに繋げるとエラー」の部分に関しては動いていたコードをそのままコピペするのではなく、適切にメソッドに切り出すことです。static void main()メソッドの中に詰め込むとややこしいことになると思います。
dodox86さん
ありがとうございます。今まで出来ていた機能までのコードを追記いたしました。そのコードとは別に要素抽出機能を追加していく形にしようと思います。
私の回答はHTMLファイルから<TITLE>タグの要素を取り出す一例であり、言いたいことはどちらかというと「機能ごとにメソッドなどの処理単位を分けましょう。その方が作りやすいしテストもデバッグもやりやすいですよ」と言うことなので、回答のコードにこだわる必要はないです。既にいただいた回答を含め、それをヒントに極力自力で解決されることを希望します。正規表現が分からなければ別の質問にするか、正規表現を使わない別の方法をがんばって作るべきです。一応申し添えておきますと、質問者であるPro01x19さんの要望するプログラムを完成させるためにコードややり方のひとつひとつにアドバイスをしていくことは無理であり、サイトの主旨にも沿っていないと考えているので、そういうことをお望みであれば私では恐らくお役に立てません。
回答2件
あなたの回答
tips
プレビュー