I'm trying to create a program that will read in an XML-based file and that will basically rewrite it in a more human friendly way, but I keep running into XMLStreamExceptions.
Here is what I have now
`import java.io.File;
/* main purpose of this class is to read and write an XML document
using tenants of STaX parsing. Eventually this should turn into a
class that will trim all but the outer 20% of the page
*/
public class XMLReader {
public static void main(String args[]) {
XMLInputFactory factory = XMLInputFactory.newInstance();
System.out.println("FACTORY:" + factory);
/*
//TODO: make input and output file take args from command line
using the programs mike sent as a reference.
File file =null;
if(args.length > 0) {
file = new File(args[0]);
}
*/
InputStream in = null; //initializing the file we will read
XMLEventReader reader = null; //intializing the eventreader
try {
in = new FileInputStream("/home/bzifkin/Proteus2/homer/src/main/java/ciir/proteus/parse/1105979_djvu.xml");
} catch (FileNotFoundException e) {
System.out.println("Could not find the file. Try again.");
}
try {
reader = factory.createXMLEventReader(in);
}
catch (XMLStreamException e) {
System.out.println("There was an XML Stream Exception, whatever that means");
}
}
}
This is the stack trace I get on the XMLStreamException
Message: expected start or end tag at com.sun.xml.internal.stream.XMLEventReaderImpl.nextTag(XMLEventReaderImpl.java:235)
at ciir.proteus.parse.XMLReader.main(XMLReader.java:61)
If I understand the comments right, you get a FileNotFoundException first, then XMLStreamException.
That sounds reasonable, because if opening the file fails, your code is printing an error message, but continues to process the undefined (null) InputStream "in".
Do something like this instead:
try {
in = new FileInputStream("/home/bzifkin/Proteus2/homer/src/main/java/ciir/proteus/parse/1105979_djvu.xml");
try {
reader = factory.createXMLEventReader(in);
}
catch (XMLStreamException e) {
System.out.println("There was an XML Stream Exception, whatever that means");
}
} catch (FileNotFoundException e) {
System.out.println("Could not find the file. Try again.");
}
Related
The task is to throw a FileNotFoundException() exception and handle it. You also need to check if the file exists on the computer and read data from it.
I wrote 2 methods, one searches for a file, the second one reads, but I am completely confused how to handle this exception. Can you suggest how to refactor this code to handle FileNotFoundException. And point out the errors of the code itself, since it is very terrible (I am just starting to learn Java)
public static boolean findFile(String path, String filename) throws FileNotFoundException {
File f = new File(path + "\\" + filename);
if (f.exists()) {
System.out.println("File found");
return true;
}
else {
System.out.println("File not found, please check that you entered the correct path and file name");
throw new FileNotFoundException();
}
}
public static ArrayList<String> readFromFile(String path, String filename) throws FileNotFoundException {
if(findFile(path,filename)) {
ArrayList<String> ip = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(path + "\\" + filename))) {
String line;
ip.add(br.readLine());
while ((line = br.readLine()) != null) {
ip.add(line);
}
} catch (IOException e) {
System.out.println(e.getMessage());
System.exit(-1);
}
return ip;
}
else {
System.out.println("Failed to read the file, check the correct path and file name");
return null;
}
}
The way you've defined the findFile method, it is always going to either return true or throw an exception. So it doesn't really make any sense to test the value returned by findFile(), or for that method to even return a value. Instead, you can assume that if the method does not throw an exception, then the file was found. For the case where it wasn't, you want to catch the exception and deal with it. Here's what that all looks like:
public static void findFile(String path, String filename) throws FileNotFoundException {
File f = new File(path + "\\" + filename);
if (f.exists()) {
System.out.println("File found");
}
else {
System.out.println("File not found, please check that you entered the correct path and file name");
throw new FileNotFoundException();
}
}
public static ArrayList<String> readFromFile(String path, String filename) throws FileNotFoundException {
try {
findFile(path,filename);
// Code to read the file...
...
}
catch (FileNotFoundException ex) {
System.out.println("Failed to read the file, check the correct path and file name");
return null;
}
}
The task is to throw a FileNotFoundException() exception and handle
it.
The answer to this question depends a lot on context.
If you are running this from the command line, you will want to add a try catch for the exception and then try again if it happens
Exception e;
do {
e = null;
try {
callAMethod();
} catch(ex) {
e=ex;
}
} while (e != null);
If you are doing this from a GUI/Swing, you can re-rethrow as a RuntimeException and use Log4j or Thread.setUncaughtExceptionHandler(..) to log the error and inform the user. The user can then try again
If you are doing this as a webapp, you will want to change the response code to 404 (FileNotFound) and indicate the file that was not found
Lastly, where you throw the FileNow FoundException, you should include a message
throw new FileNotFoundException(/*incude a string with the file path*/);
I am trying write to a csv file. After the execution of the code bellow the csv file is still empty.
File is in folder .../webapp/resources/.
This is my dao class:
public class UserDaoImpl implements UserDao {
private Resource cvsFile;
public void setCvsFile(Resource cvsFile) {
this.cvsFile = cvsFile;
}
#Override
public void createUser(User user) {
String userPropertiesAsString = user.getId() + "," + user.getName()
+ "," + user.getSurname() +"\n";;
System.out.println(cvsFile.getFilename());
FileWriter outputStream = null;
try {
outputStream = new FileWriter(cvsFile.getFile());
outputStream.append(userPropertiesAsString);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public List<User> getAll() {
return null;
}
}
This is a part of beans.xml.
<bean id="userDao" class="pl.project.dao.UserDaoImpl"
p:cvsFile="/resources/users.cvs"/>
Program compiles and doesn't throw any exceptions but CSV file is empty.
If you're running your app in IDE, the /webapp/resources used for running app will differ from the /webapp/resources in your IDE. Try to log full path to file and check there.
try using outputStream.flush() as the final statement in the first of the try block.
I think you're looking at the wrong file. If you specify an absolute path /resources/users.cvs, then it probably won't be written into the a folder relative to the webapp. Instead, it will be written to /resources/users.cvs
So the first step is to always log an absolute path to make sure the file is where you expect it.
Try with this code, it will at least tell you where the problem lies (Java 7+):
// Why doesn't this method throw an IOException?
#Override
public void createUser(final User user)
{
final String s = String.format("%s,%s,%s",
Objects.requireNonNull(user).getId(),
user.getName(), user.getSurname()
);
// Note: supposes that .getFile() returns a File object
final Path path = csvFile.getFile().toPath().toAbsolutePath();
final Path csv;
// Note: this supposes that the CSV is supposed to exist!
try {
csv = path.toRealPath();
} catch (IOException e) {
throw new RuntimeException("cannot locate CSV " + path, e);
}
try (
// Note: default is to TRUNCATE the destination.
// If you want to append, add StandardOpenOption.APPEND.
// See javadoc for more details.
final BufferedWriter writer = Files.newBufferedWriter(csv,
StandardCharsets.UTF_8);
) {
writer.write(s);
writer.newLine();
writer.flush();
} catch (IOException e) {
throw new RuntimeException("write failure", e);
}
}
Okay, this is going to be a bit long. So I made a junit test class to test my program. I wanted to test if a method that uses a Scanner to read a file into the program threw and exception, if the file didn't exist like this:
#Test
public void testLoadAsTextFileNotFound()
{
File fileToDelete = new File("StoredWebPage.txt");
if(fileToDelete.delete()==false) {
System.out.println("testLoadAsTextFileNotFound - failed");
fail("Could not delete file");
}
try{
assertTrue(tester.loadAsText() == 1);
System.out.println("testLoadAsTextFileNotFound - passed");
} catch(AssertionError e) {
System.out.println("testLoadAsTextFileNotFound - failed");
fail("Did not catch Exception");
}
}
But the test fails at "could not delete file", so I did some searching. The path is correct, I have permissions to the file because the program made it in the first place. So the only other option would be, that a stream to or from the file is still running. So I checked the method, and the other method that uses the file, and as far as I can, both streams are closed inside the methods.
protected String storedSite; //an instance variable
/**
* Store the instance variable as text in a file
*/
public void storeAsText()
{
PrintStream fileOut = null;
try{
File file = new File("StoredWebPage.txt");
if (!file.exists()) {
file.createNewFile();
}
fileOut = new PrintStream("StoredWebPage.txt");
fileOut.print(storedSite);
fileOut.flush();
fileOut.close();
} catch(Exception e) {
if(e instanceof FileNotFoundException) {
System.out.println("File not found");
}
fileOut.close();
} finally {
if(fileOut != null)
fileOut.close();
}
}
/**
* Loads the file into the program
*/
public int loadAsText()
{
storedSite = ""; //cleansing storedSite before new webpage is stored
Scanner fileLoader = null;
try {
fileLoader = new Scanner(new File("StoredWebPage.txt"));
String inputLine;
while((inputLine = fileLoader.nextLine()) != null)
storedSite = storedSite+inputLine;
fileLoader.close();
} catch(Exception e) {
if(e instanceof FileNotFoundException) {
System.out.println("File not found");
return 1;
}
System.out.println("an Exception was caught");
fileLoader.close();
} finally {
if(fileLoader!=null)
fileLoader.close();
}
return 0; //return value is for testing purposes only
}
I'm out of ideas. Why can't I delete my file?
EDIT: i've edited the code, but still this give me the same problem :S
You have two problems here. The first is that if an exception is thrown during your write to the file, the output stream is not closed (same for the read):
try {
OutputStream someOutput = /* a new stream */;
/* write */
someOutput.close();
The second problem is that if there's an exception you aren't notified:
} catch (Exception e) {
if (e instanceof FileNotFoundException) {
/* do something */
}
/* else eat it */
}
So the problem is almost certainly that some other exception is being thrown and you don't know about it.
The 'correct' idiom to close a stream is the following:
OutputStream someOutput = null;
try {
someOutput = /* a new stream */;
/* write */
} catch (Exception e) {
/* and do something with ALL exceptions */
} finally {
if (someOutput != null) someOutput.close();
}
Or in Java 7 you can use try-with-resources.
I have a Problem with commons-net FTPClient. If I download a file from my ftp server wirth retrieveFileStream() it works, but I get the result '150 Opening BINARY mode data connection for ...'. If I call noop() I get '226 Transfer complete' as result. For every following operation I get the result of the prvious operation.
I found out, that FTPClient reads results until end of line, if there are two result lines (as after retrieveFileStream()), I get the second one after the next command. I did a workaround by overriding FTPClient.retrieveFileStream() like this:
public static void main(String[] args){
try {
MyFTPClient ftpClient = new MyFTPClient();
try {
ftpClient.connect(ftphost, 21);
if(!ftpClient.login( ftpuser, ftppassword )){
throw new RuntimeException(ftpClient.getReplyString());
}
if(!ftpClient.changeWorkingDirectory("in")){
throw new RuntimeException(ftpClient.getReplyString());
}
FTPFile[] files = ftpClient.listFiles();
for(FTPFile file: files){
if(file.getName().startsWith(FILENAME) && (file.getType() == FTPFile.FILE_TYPE)){
InputStream in = ftpClient.retrieveFileStream(file.getName());
CsvFile csvFile = new CsvFile(in, "ISO-8859-1", ';', "yyyyMMdd", "#.00", Locale.US, false);
in.close();
in = null;
System.out.println(ftpClient.getReplyString());
System.out.println(ftpClient.readLine());
System.out.println(ftpClient.rnfr(file.getName()));
System.out.println(ftpClient.getReplyString());
System.out.println(ftpClient.rnto("x" + file.getName()));
System.out.println(ftpClient.getReplyString());
}
}
if(!ftpClient.logout()){
throw new RuntimeException(ftpClient.getReplyString());
}
} finally {
ftpClient.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static class MyFTPClient extends FTPClient{
public String readLine(){
try {
__getReplyNoReport();
} catch (IOException e) {
}
return getReplyString();
}
}
The call of the method readLine() gets me the additional Line of result.
But is this a bug of FTPClient or is it a problem of my ftp-server? The Problem of that workaround is, that the method blocks, if there is only one line of response.
Thanx for your help
Stephan
Sometimes it helps, reading the manual. A call of completePendingCommand() works
I am trying to read a text file, "text.txt", packaged at the root as a part of my jar file. in one case, my code calls class.getResourceAsStream("/test.txt") and in another case, my code calls class.getClassLoader().getResourceAsStream("/test.txt").
The first call gets the correct data but the second one doesn't get anything. any idea?
public static void main(String[] args) {
InputStream is = null;
try {
is = TestLoadResourcesByClass.class.getResourceAsStream("/test.txt");
StringWriter writer = new StringWriter();
IOUtils.copy(is, writer);
System.out.println(writer.toString());
} catch(Exception ex) {
ex.printStackTrace();
} finally {
if(null != is) { try { is.close(); } catch(Exception ex) { } }
}
}
public static void main(String[] args) {
InputStream is = null;
try {
is = TestLoadResourcesByClassLoader.class.getClassLoader().getResourceAsStream("/test.txt");
StringWriter writer = new StringWriter();
IOUtils.copy(is, writer);
System.out.println(writer.toString());
} catch(Exception ex) {
ex.printStackTrace();
} finally {
if(null != is) { try { is.close(); } catch(Exception ex) { }
}
}
let's say i have 2 jar files
first.jar : contains TestLoadResourcesByClass.class (code to read test.txt)
second.jar : contains "test.txt" at the root
and then i run my code as follows
java -cp first.jar;second.jar;commons-io-2.4.jar test.TestLoadByClass
i also get no output at the console. is that because the classes/resources in second.jar have not been loaded? in fact, i get a null pointer exception (input stream is null).
any idea on what's going on?
It is explained in the javadoc for Class.getResourceAsStream. That method removes the / from the start of resource names to create the absolute resource name that it gives to ClassLoader.getResourceAsStream. If you want to call ClassLoader.getResourceAsStream directly then you should omit the / at the start.