I have a program that creates a webgraph from text files. Every Time I run it I get the same message that says "Scanner Closed."
//constant final variables
public static final String PAGES_FILE = "pages.txt";
public static final String LINKS_FILE = "links.txt";
// webgraph object var
private WebGraph web;
// searchEngine constructor.
public SearchEngine() throws FileNotFoundException {
web = WebGraph.buildFromFiles(PAGES_FILE, LINKS_FILE);
}
Scanner Portion
try {
System.out.println("Loading WebGraph data...");
SearchEngine engine = new SearchEngine();
System.out.println("Success!");
Scanner scanner = new Scanner(System.in);
I have the scanner.close() right after the try block which contains all the possible user inputs. I have also attached an image of what should be happening once I run the program. Any ideas what could be going wrong? If any other code is needed I can provide that.Sample Program
Here is the image of what I am getting My Run
This is the code for the "buildFromFiles"
public static WebGraph buildFromFiles(String pagesFile, String linksFile)
throws IllegalArgumentException, FileNotFoundException {
WebGraph webGraph = new WebGraph();
File filePages = new File(pagesFile);
File fileLinks = new File(linksFile);
if (filePages.exists() && fileLinks.exists() && filePages.isFile() && fileLinks.isFile()) {
Scanner pageScanner = new Scanner(filePages);
while (pageScanner.hasNextLine()) {
String[] pageData = pageScanner.nextLine().split("\\s+");
String url = pageData[0];
ArrayList<String> keywords = new ArrayList<String>();
for (int i = 1; i < pageData.length; i++) {
keywords.add(pageData[i]);
}
webGraph.addPage(url, keywords);
}
pageScanner.close();
Scanner linkScanner = new Scanner(fileLinks);
while (linkScanner.hasNextLine()) {
String[] linkData = pageScanner.nextLine().split("\\s+");
webGraph.addLink(linkData[0], linkData[1]);
}
linkScanner.close();
} else {
throw new IllegalArgumentException();
}
return webGraph;
}
Related
I am new to Java and I have a project to do, so I have a java file and the user have to choose from a listing of files in a directory. The input from user is saved in a variable (fileName). I want to use that variable in another java file for doing some other work. I searched online but didn't find any solution that works for me. Probably I've done something wrong.
code of the first file:
public class Director {
private static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
public static void main(String[] args) throws IOException {
// Creates an array in which we will store the names of files and directories
String[] pathnames;
// Creates a new File instance by converting the given pathname string
// into an abstract pathname
File f = new File("C:\\Users\\miltos\\Desktop\\polimesa\\available_videos");
// Populates the array with names of files and directories
pathnames = f.list();
System.out.println("Files in the directory:");
// For each pathname in the pathnames array
for (String pathname : pathnames) {
// Print the names of files and directories
System.out.println(pathname);
}
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Enter file name");
String fileName = myObj.nextLine();
File source = new File("C:\\Users\\miltos\\Desktop\\polimesa\\available_videos\\" + fileName);
File dest = new File("C:\\Users\\miltos\\Desktop\\polimesa\\raw_videos\\" + fileName);
copyFileUsingStream(source, dest);
}
}
code of the second file that i want to use the input:
public class TestFFMpeg {
static Logger log = LogManager.getLogger(TestFFMpeg.class);
public static void main(String[] args) {
FFmpeg ffmpeg = null;
FFprobe ffprobe = null;
try {
log.debug("Initialising FFMpegClient");
ffmpeg = new FFmpeg("C:\\Users\\miltos\\ffmpeg\\bin\\ffmpeg.exe");
ffprobe = new FFprobe("C:\\Users\\miltos\\ffmpeg\\bin\\ffprobe.exe");
} catch (IOException e) {
e.printStackTrace();
}
log.debug("Creating the transcoding");
FFmpegBuilder builder = new FFmpegBuilder()
.setInput("C:\\Users\\miltos\\Desktop\\polimesa\\raw_videos\\" + filename) //updated
.addOutput("C:\\Users\\miltos\\Desktop\\polimesa\\videos\\" + filename) //updated
.setVideoBitRate(200000)
.done();
log.debug("Creating the executor");
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
log.debug("Starting the transcoding");
// Run a one-pass encode
executor.createJob(builder).run();
log.debug("Transcoding finished");
}
}
I created a variable names filename in class second also, which you will pass from the class one , while creating an object of class second like
TestFFMpeg obj = new TestFFMpeg();
obj.methodInSecondClass(filename);
Second Class :
public class TestFFMpeg {
static Logger log = LogManager.getLogger(TestFFMpeg.class);
public void methodInSecondClass(String filename){
FFmpeg ffmpeg = null;
FFprobe ffprobe = null;
try {
log.debug("Initialising FFMpegClient");
ffmpeg = new FFmpeg("C:\\Users\\miltos\\ffmpeg\\bin\\ffmpeg.exe");
ffprobe = new FFprobe("C:\\Users\\miltos\\ffmpeg\\bin\\ffprobe.exe");
} catch (IOException e) {
e.printStackTrace();
}
log.debug("Creating the transcoding");
FFmpegBuilder builder = new FFmpegBuilder()
.setInput("C:\\Users\\miltos\\Desktop\\polimesa\\available_videos\\"+filename) //this is where i want the same variable
.addOutput("C:\\Users\\miltos\\Desktop\\polimesa\\videos\\"+filename) //this is where i want the same variable
.setVideoBitRate(200000)
.done();
log.debug("Creating the executor");
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
log.debug("Starting the transcoding");
// Run a one-pass encode
executor.createJob(builder).run();
log.debug("Transcoding finished");
}
}
I just started with this project and tried to check whether I was going the right way. I run this code but got one "FileNotFound exception must be caught or thrown" error. What do I do now? Am I going the right way?
package com.company;
import java.util.Scanner;
import java.io.File;
public class Main
{
public static void main(String[] args)
{
Game game = new Game();
String s = game.OpenFile();
System.out.println(s);
}
}
class Game
{
public Game(){
moviename = " ";
}
private String moviename;
public String OpenFile()
{
File file = new File("movienames.txt");
Scanner ip = new Scanner(file);
int rnum = (int)(Math.random()*10)+1;
int count = 0;
while(ip.hasNextLine())
{
moviename = ip.nextLine();
count++;
if(count==rnum)
{
break;
}
}
return moviename;
}
Yes you are going in the right way. What this warning is saying is that you must handle the FileNotFound exception. You have two options: Throw it or surround the code in a try-catch block:
Throwing the exception:
public String OpenFile() throws FileNotFoundException
{
File file = new File("movienames.txt");
Scanner ip = new Scanner(file);
int rnum = (int)(Math.random()*10)+1;
int count = 0;
while(ip.hasNextLine())
{
moviename = ip.nextLine();
count++;
if(count==rnum)
{
break;
}
}
return moviename;
}
Try-Catch:
public String OpenFile()
{
try {
File file = new File("movienames.txt");
Scanner ip = new Scanner(file);
int rnum = (int)(Math.random()*10)+1;
int count = 0;
while(ip.hasNextLine())
{
moviename = ip.nextLine();
count++;
if(count==rnum)
{
break;
}
}
}catch(Exception e) {
e.printStackTrace();
}
return moviename;
Some good readings:
Difference between try-catch and throw in java
https://beginnersbook.com/2013/04/try-catch-in-java/
I am having a bit of an issues trying to pass in a file read by my program and sorted accordantly. I am not used to working with files, and i ran out of ideas as to how this could be achieved.
/////////////////////////////////////// class reads file ///////////////////////////////////
import java.io.*;
public class InFileReader {
private BufferedReader inputStream = null;
private String fileLine;
private StringBuilder sb;
public String getFile(File fileRead) throws FileNotFoundException,
IOException {
inputStream = new BufferedReader(new FileReader(fileRead)); //reads files
sb = new StringBuilder();
while((fileLine = inputStream.readLine()) != null){//keep reading lines in file till there is none
sb.append(fileLine).append("\n");
}
return sb.toString(); //returns StringBuffer read values in String form
}
}
///////////////////////////////////////////////////// end of read file class ///////////////////////
public void getFile(File fileRead) throws FileNotFoundException,
IOException {
try {
String input = fileReader.getFile(fileRead.getAbsoluteFile());
HashMap<Integer, Thing.Ship> hashmap = new HashMap<>();
while (!input.isEmpty()) { // as long as there is data in the file keep looping
Scanner sc = new Scanner(input); // scan file
if (!input.startsWith("//")) { // take out "//" from directory
String type = "";
if (sc.hasNext()) { // if there are character lines get next line
type = sc.next();
}
if (type.equalsIgnoreCase("port")) { // looks for "port"
world.assignPort(new Thing.SeaPort(sc)); // assigns value to Seaport
} else if (type.equalsIgnoreCase("dock")) {
world.assignDock(new Thing.Dock(sc));
} else if (type.equalsIgnoreCase("ship")) {
Thing.Ship s = new Thing.Ship(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("pship")) {
Thing.Ship s = new Thing.PassengerShip(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("cship")) {
Thing.Ship s = new Thing.CargoShip(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("person")) {
world.assignPerson(new Thing.Person(sc));
}
}
}
//inputOut.setText(type);
inputOut.setText(world.toString());
} catch (Exception e) {
System.out.println(e + "-----");
}
}
Here fileRead knows where to find the file to be read "C:\Users\abe\IdeaProjects\CreateSeaPortDataFile\src\text.txt"
public void getFile(File fileRead) throws FileNotFoundException,
IOException {
this is where things just fall apart:
String input = fileReader.getFile(fileRead.getAbsoluteFile());
My intent here is to pass the location of the file so that the getFile class can read it and then be sorted into the hashmap.
again i am not familiar with how to work with file, any suggestion or comment would be greatly appreciated.
thank you in advanced.
If you get a FileNotFoundException then the file was not found.
You say the filename was "C:\Users\abe\IdeaProjects\CreateSeaPortDataFile\src\text.txt".
If you type that name in the code you must escape the backslash:
"C:\\Users\\abe\\IdeaProjects\\CreateSeaPortDataFile\\src\\text.txt".
I'm trying to create program downloads historical data from Yahoo Finance and then displays the historical data for the last year based a stock symbol entered into the main class.
For some reason, I keep getting a 401 code when I try to run my program. The URL displayed in the 401 error gets me where I want to go if I copy and paste into a browser.
Not sure what I am doing wrong here.
Here's my code for the StockDownloader Class:
import java.util.GregorianCalendar;
import java.util.Calendar;
import java.util.ArrayList;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;
public class StockDownloader
{
public static final int DATE = 0;
public static final int OPEN = 1;
public static final int HIGH = 2;
public static final int LOW = 3;
public static final int CLOSE = 4;
public static final int VOLUME = 6;
public static final int ADJCLOSE = 5;
private ArrayList<GregorianCalendar> dates;
private ArrayList<Double> opens;
private ArrayList<Double> highs;
private ArrayList<Double> lows;
private ArrayList<Double> closes;
private ArrayList<Integer> volumes;
private ArrayList<Double> adjCloses;
public StockDownloader (String symbol)
{
dates = new ArrayList<GregorianCalendar>();
opens = new ArrayList<Double>();
highs = new ArrayList<Double>();
lows = new ArrayList<Double>();
closes = new ArrayList<Double>();
volumes = new ArrayList<Integer>();
adjCloses = new ArrayList<Double>();
//https://query1.finance.yahoo.com/v7/finance/download/IBM?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI
String url = "https://query1.finance.yahoo.com/v7/finance/download/"+symbol+"?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI";
try
{
URL yhoofin = new URL(url);
URLConnection data = yhoofin.openConnection();
Scanner input = new Scanner(data.getInputStream());
if(input.hasNext())//skip line...it's just the header
input.nextLine();
//start reading data
while(input.hasNextLine())
{
String line = input.nextLine();
//TODO- connec tdata to the correct ArrayList
System.out.println(line);
}
}
catch (Exception e)
{
System.err.println(e);
}
}
public ArrayList<GregorianCalendar> getDates()
{
return dates;
}
/*public ArrayList<Double> get Opens()
{
}*/
}
And my code for the main class:
public class Stocks {
public static void main(String[] args)
{
StockDownloader test = new StockDownloader("DCTH");
}
}
Help please
Looks like yahoo has changed the mode of ways of accessing finance API. You need to add a cookie to URL connection. Have changed your code and it works for me.
public class StockDownloader {
public static final int DATE = 0;
public static final int OPEN = 1;
public static final int HIGH = 2;
public static final int LOW = 3;
public static final int CLOSE = 4;
public static final int VOLUME = 6;
public static final int ADJCLOSE = 5;
private ArrayList<GregorianCalendar> dates;
private ArrayList<Double> opens;
private ArrayList<Double> highs;
private ArrayList<Double> lows;
private ArrayList<Double> closes;
private ArrayList<Integer> volumes;
private ArrayList<Double> adjCloses;
private String finalCrumb;
public StockDownloader(String symbol) {
dates = new ArrayList<GregorianCalendar>();
opens = new ArrayList<Double>();
highs = new ArrayList<Double>();
lows = new ArrayList<Double>();
closes = new ArrayList<Double>();
volumes = new ArrayList<Integer>();
adjCloses = new ArrayList<Double>();
try {
// Hit the below URL to get the cookies and the crumb value to access the finance API
String mainURL = "https://uk.finance.yahoo.com/quote/"+symbol+"/history";
Map<String, List<String>> setCookies = setCookies(mainURL);
// https://query1.finance.yahoo.com/v7/finance/download/IBM?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=2WsiR.p1KtI
// will need to append the crumb in the end to the below URL to have the actual crumb rather than the hardcoded one
String url = "https://query1.finance.yahoo.com/v7/finance/download/" + symbol
+ "?period1=1467352800&period2=1498888800&interval=1d&events=history&crumb=" + finalCrumb;
URL yhoofin = new URL(url);
URLConnection data = yhoofin.openConnection();
// get the list of Set-Cookie cookies from response headers
List<String> cookies = setCookies.get("Set-Cookie");
if (cookies != null) {
for (String c : cookies)
data.setRequestProperty("Cookie", c);
}
Scanner input = new Scanner(data.getInputStream());
if (input.hasNext())// skip line...it's just the header
input.nextLine();
// start reading data
while (input.hasNextLine()) {
String line = input.nextLine();
// TODO- connec tdata to the correct ArrayList
System.out.println(line);
}
input.close();
}
catch (Exception e) {
System.err.println(e);
}
}
// This method extracts the crumb and is being called from setCookies() method
private String searchCrumb(URLConnection con) throws IOException {
String crumb = null;
InputStream inStream = con.getInputStream();
InputStreamReader irdr = new InputStreamReader(inStream);
BufferedReader rsv = new BufferedReader(irdr);
Pattern crumbPattern = Pattern.compile(".*\"CrumbStore\":\\{\"crumb\":\"([^\"]+)\"\\}.*");
String line = null;
while (crumb == null && (line = rsv.readLine()) != null) {
Matcher matcher = crumbPattern.matcher(line);
if (matcher.matches())
crumb = matcher.group(1);
}
rsv.close();
System.out.println("Crumb is : "+crumb);
return crumb;
}
// This method extracts the cookies from response headers and passes the same con object to searchCrumb()
// method to extract the crumb and set the crumb value in finalCrumb global variable
private Map<String, List<String>> setCookies(String mainUrl) throws IOException {
// "https://finance.yahoo.com/quote/SPY";
Map<String, List<String>> map = new HashMap<String, List<String>>();
URL url = new URL(mainUrl);
URLConnection con = url.openConnection();
finalCrumb = searchCrumb(con);
for (Map.Entry<String, List<String>> entry : con.getHeaderFields().entrySet()) {
if (entry.getKey() == null || !entry.getKey().equals("Set-Cookie"))
continue;
for (String s : entry.getValue()) {
map.put(entry.getKey(), entry.getValue());
System.out.println(map);
}
}
return map;
}
public ArrayList<GregorianCalendar> getDates() {
return dates;
}
}
Have got much details regarding the finance API here.
Give a try!
A 401 error code means the user is unauthorised. Take a look again at YQL and if you are sure that everything you did is correct but the issue is still there then check out this library. This makes life easier in using Yahoo Finance API.
The method reads the data for the First class and second Class using scanner and then it stores them in the ArrayList the tow class. First and Second are inherited From Main Class. The problem I have is the duplication I created to objects.
How can I only create one and use it for both.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
public class Auto {
private ArrayList<Main> lists;
public Auto() {
lists = new ArrayList<Main>();
}
public void storeData(Main main) {
list.add(main);
}
public void readFile(String filePath) throws FileNotFoundException {
File file = new File(filePath);
Scanner input = new Scanner(file);
String dataToBe;
while (input.hasNext()) {
String lines = input.nextLine().trim();
Scanner scanner = new Scanner(lines).useDelimiter("\n[ ]*,");
if (lines.startsWith("Data")) {
if (lines.startsWith("FirstData")) {
dataToBe = "first";
} else if (lines.startsWith("SecondData")) {
dataToBe = "second";
}
} else if (dataToBe.equals("first")) {
Main main = new First();
main.readData(scanner);
storeData(main);
} else if (dataToBe.equals("second")) {
Main main = new Second();
main.readData(scanner);
storeData(main);
}
}
}
}
Okay, you might think its longwinded, but it's probably how I would do it under your restrictions.
public void readFile(String filePath) throws FileNotFoundException {
final Pattern pattern = Pattern.compile("\n[ ]*,");
final Scanner fileInput = new Scanner(new File(filePath));
while (fileInput.hasNextLine()) {
final String line = fileInput.nextLine().trim();
final Matcher matcher = pattern.matcher(line);
final StringBuilder builder = new StringBuilder();
byte flag = 0;
while (matcher.find()) {
final String match = matcher.group();
if(match.startsWith("FirstData")){ flag = 1;}
else if(match.startsWith("SecondData")){flag = 2;}
builder.append(line).append(",");
}
Main mainObj = (flag == 1) ? (new First()) : (flag == 2) ? (new Second()) : null;
if(null != mainObj){
mainObj.readData(builder.toString());
}
}
}
The approach above does require you to accept a String instead of a Scanner in the parameter, but the CSV format passed to each method lets the behaviour of each class handle the work.