From 7a645cb4f73bf697d166ede24e81f0d56f5b68b3 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 2 May 2014 18:22:29 +0200 Subject: Refactor DataWriter once more to group a file The input and output file are closely related, do not burden others with tracking which output and input need to be matched. --- src/io/DataWriter.java | 116 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 37 deletions(-) diff --git a/src/io/DataWriter.java b/src/io/DataWriter.java index 841b27d..d762fee 100644 --- a/src/io/DataWriter.java +++ b/src/io/DataWriter.java @@ -26,12 +26,12 @@ public class DataWriter implements ResultListener { /** * The writer for the tweet stream. */ - private final OutputStream m_tweetWriter; + private final Store m_tweet; /** * the writer for the profile stream. */ - private final OutputStream m_profileWriter; + private final Store m_profile; /** * the buffer of tweet ids that already exist. @@ -55,67 +55,50 @@ public class DataWriter implements ResultListener { */ public DataWriter(final String profilesName, final String tweetsName) throws IOException { - m_profileIdSet = readIds(profilesName); - m_profileWriter = getFileWriter(profilesName); + m_profile = getStore(profilesName); + m_profileIdSet = readIds(m_profile); - m_tweetIdSet = readIds(tweetsName); - m_tweetWriter = getFileWriter(tweetsName); + m_tweet = getStore(profilesName); + m_tweetIdSet = readIds(m_tweet); } /** - * Given a filename, return a suitable input stream. + * For a given filename, get an instance that provides I/O. * - * @param tweetsName File name. - * @return A stream from which JSON objects can be read (one per line). - * @throws IOException + * @param filename File to read/write. + * @return A Store instance providing read and write access. + * @throws IOException if the target file cannot be read or written. */ - protected InputStream getFileReader(String tweetsName) - throws IOException { - return new FileInputStream(tweetsName); - } - - /** - * Given a filename, return a suitable output stream. - * - * @param tweetsName File name. - * @return A stream to which JSON objects can be written (one per line). - * @throws IOException - */ - protected OutputStream getFileWriter(String tweetsName) - throws IOException { - return new FileOutputStream(tweetsName, true); + protected Store getStore(String filename) throws IOException { + return new SimpleFileStore(filename); } public void close() { - try { - m_tweetWriter.close(); - m_profileWriter.close(); - } catch (IOException ex) { - getLogger().log(Level.SEVERE, null, ex); - } + m_tweet.close(); + m_profile.close(); } @Override public void profileGenerated(JSONObject obj) { - writeObject(obj, m_profileWriter, m_profileIdSet); + writeObject(obj, m_profile.getOutputStream(), m_profileIdSet); } @Override public void tweetGenerated(JSONObject obj) { - writeObject(obj, m_tweetWriter, m_tweetIdSet); + writeObject(obj, m_tweet.getOutputStream(), m_tweetIdSet); } /** * Read the current existing tweetName and profileName filenames and fill * the existing id set. * - * @param filename The file to parse. + * @param is An input stream that provides JSON objects. * @return The set of ids, may be empty if the fill does not exist. */ - private Set readIds(String filename) throws IOException { + private Set readIds(Store store) throws IOException { Set idSet = new HashSet<>(); try { - InputStream is = getFileReader(filename); + InputStream is = store.getInputStream(); Scanner reader = new Scanner(is); // parse each line into a JSONObject, read the id and add it to // the set of ids. @@ -127,7 +110,7 @@ public class DataWriter implements ResultListener { } catch (FileNotFoundException ex) { // ignore, file will be created if necessary. } catch (JSONException ex) { - getLogger().log(Level.WARNING, filename + getLogger().log(Level.WARNING, store.getFileName() + ": File is only partially processed", ex); } return idSet; @@ -162,4 +145,63 @@ public class DataWriter implements ResultListener { private Logger getLogger() { return Logger.getLogger(getClass().getName()); } + + abstract class Store { + + private final String filename; + protected OutputStream os; + + Store(String filename) { + this.filename = filename; + } + + /** + * @return The file name associated with this store. + */ + public String getFileName() { + return filename; + } + + /** + * Properly closes a file, flushing any buffers. + */ + public void close() { + try { + os.close(); + } catch (IOException ex) { + Logger.getLogger(getClass().getName()).log(Level.WARNING, + "Could not close " + getFileName(), ex); + } + } + + /** + * Returns a previously opened writable file stream. + * + * @return A stream to which JSON objects can be written (one per line). + */ + public OutputStream getOutputStream() { + return os; + } + + /** + * Opens a new input stream for the file. + * + * @return A stream from which JSON objects can be read (one per line). + * @throws IOException if no input file can be retrieved. + */ + abstract public InputStream getInputStream() throws IOException; + } + + class SimpleFileStore extends Store { + + SimpleFileStore(String filename) throws FileNotFoundException { + super(filename); + os = new FileOutputStream(getFileName(), true); + } + + @Override + public InputStream getInputStream() throws FileNotFoundException { + return new FileInputStream(getFileName()); + } + } } -- cgit v1.2.1