Well what i am trying to achieve is to save pairs of words in a sentence and if the word is already there , i am trying to save a list of words against one.
To save the pairing as there could many millions as my data set file is very large , i opted for orientdb. I dont know if i am approaching it correctly but orientdb is very slow. After 8 hours of running it has only made pairs for 12000 sentences.
As far as i have checked the major slowdown was in browsing cluster.
Attached is my code, please if ant one can give any pointers over my approach.
public static void main(String[] args) {
// TODO Auto-generated method stub
Main m = new Main();
m.openDatabase();
m.readFile("train_v2.txt");
m.closeDatabase();
}
}
class Main {
ODatabaseDocumentTx db;
Map<String, Object> index;
List<Object> list = null;
String pairing[];
ODocument doc;
Main() {
}
public void closeDatabase() {
if (!db.isClosed()) {
db.close();
}
}
void openDatabase() {
db = new ODatabaseDocumentTx("local:/databases/model").open("admin",
"admin");
doc = new ODocument("final");
}
public void readFile(String filename) {
InputStream ins = null; // raw byte-stream
Reader r = null; // cooked reader
int i = 1;
BufferedReader br = null; // buffered for readLine()
try {
String s;
ins = new FileInputStream(filename);
r = new InputStreamReader(ins, "UTF-8"); // leave charset out
// for
// default
br = new BufferedReader(r);
while ((s = br.readLine()) != null) {
System.out.println("" + i);
createTermPair(s.replaceAll("[^\\w ]", "").trim());
i++;
}
} catch (Exception e) {
System.err.println(e.getMessage()); // handle exception
} finally {
closeDatabase();
if (br != null) {
try {
br.close();
} catch (Throwable t) { /* ensure close happens */
}
}
if (r != null) {
try {
r.close();
} catch (Throwable t) { /* ensure close happens */
}
}
if (ins != null) {
try {
ins.close();
} catch (Throwable t) { /* ensure close happens */
}
}
}
}
private void createTermPair(String phrase) {
phrase = phrase + " .";
String[] word = phrase.split(" ");
for (int i = 0; i < word.length - 1; i++) {
if (!word[i].trim().equalsIgnoreCase("")
&& !word[i + 1].trim().equalsIgnoreCase("")) {
String wordFirst = word[i].toLowerCase().trim();
String wordSecond = word[i + 1].toLowerCase().trim();
String pair = wordFirst + " " + wordSecond;
checkForPairAndWrite(pair);
}
}
}
private void checkForPairAndWrite(String pair) {
try {
pairing = pair.trim().split(" ");
if (!pairing[1].equalsIgnoreCase(" ")) {
index = new HashMap<String, Object>();
for (ODocument docr : db.browseCluster("final")) {
list = docr.field(pairing[0]);
}
if (list == null) {
list = new ArrayList<>();
}
list.add("" + pairing[1]);
if (list.size() >= 1)
index.put(pairing[0], list);
doc.fields(index);
doc.save();
}// for (int i = 0; i < list.size(); i++) {
// System.out.println("" + list.get(i));
// }
} catch (Exception e) {
}
return;
}
}
Related
I'm having difficulty attempting to print the contents of my Graph using a toString method. Moreover, I do not receive an error when I add my Vertex to my Graph but I am unsure if I am properly adding my Vertexes. Thank you to anyone for any help!
Here's the App.
public class App
{
public static void main(String[] args)
{
File EdgeFile = new File("/User/src/main/java/edu.sdsu.cs/datastructures/threeVertexList.csv");
File VertexFile = new File("User/src/main/java/edu.sdsu.cs/datastructures/threeEdgesList.csv");
if (EdgeFile.exists() && EdgeFile.isFile() && VertexFile.exists() && VertexFile.isFile()) // Checks to see if Files are in existence
{
IGraph<String, Integer> Graph = new WDGraph<>(); // Instantiating the Graph
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("cities.csv"));
String read = null;
while ((read = in.readLine()) != null) {
String[] split = read.split(",");
for (String part : split) {
Graph.addVertex(part);
}
}
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) {
}
}
}
else
{
System.out.println("Error: Incorrect number of input arguments (0 or 2 expected), X provided");
}
toString(); // method to overwrite to check contents of Vertices
}
}
Here is my Graph.
class WDGraph<V,E> implements IGraph<V,E> {
private final List<IVertex> nodes;
private final List<IEdge> edges;
WDGraph() {
this.nodes = nodes;
this.edges = edges;
}
private List<IVertex> getVertexes() {
return nodes;
}
private List<IEdge> getEdges() {
return edges;
}
Just wondering what I have done wrong here I'm getting an error in the method setLine() which is:
error: incompatible types: String[] cannot be converted to State[]
Im not too sure on what to do to fix it since I need the line to be split and stored in that state array so I can determine whether if it is a state or location when reading from a csv file.
public static void readFile(String inFilename)
{
FileInputStream fileStrm = null;
InputStreamReader rdr;
BufferedReader bufRdr;
int stateCount = 0, locationCount = 0;
String line;
try
{
fileStrm = new FileInputStream(inFilename);
rdr = new InputStreamReader(fileStrm);
bufRdr = new BufferedReader(rdr);
line = bufRdr.readLine();
while (line != null)
{
if (line.startsWith("STATE"))
{
stateCount++;
}
else if (line.startsWith("LOCATION"))
{
locationCount++;
}
line = bufRdr.readLine();
}
fileStrm.close();
State[] state = new State[stateCount];
Location[] location = new Location[locationCount];
}
catch (IOException e)
{
if (fileStrm != null)
{
try { fileStrm.close(); } catch (IOException ex2) { }
}
System.out.println("Error in file processing: " + e.getMessage());
}
}
public static void processLine(String csvRow)
{
String thisToken = null;
StringTokenizer strTok;
strTok = new StringTokenizer(csvRow, ":");
while (strTok.hasMoreTokens())
{
thisToken = strTok.nextToken();
System.out.print(thisToken + " ");
}
System.out.println("");
}
public static void setLine(State[] state, Location[] location, int stateCount, int locationCount, String line)
{
int i;
state = new State[stateCount];
state = line.split("="); <--- ERROR
for( i = 0; i < stateCount; i++)
{
}
}
public static void writeOneRow(String inFilename)
{
FileOutputStream fileStrm = null;
PrintWriter pw;
try
{
fileStrm = new FileOutputStream(inFilename);
pw = new PrintWriter(fileStrm);
pw.println();
pw.close();
}
catch (IOException e)
{
if (fileStrm != null)
{
try
{
fileStrm.close();
}
catch (IOException ex2)
{}
}
System.out.println("Error in writing to file: " + e.getMessage());
}
}
This error occurs, as it just says 'String[] cannot be converted to State[]'. That is like you wanted to store an Integer into a String, it's the same, because the types don't have a relation to each other (parent -> child).
So if you want to solve your problem you need a method which converts the String[] into a State[]. Something like this:
private State[] toStateArray(String[] strings){
final State[] states = new State[strings.length];
for(int i = strings.length-1; i >= 0; i--){
states[i] = new State(strings[i]); // here you have to decide how to convert String to State
}
return states;
}
I have the following textfile contains the information that will be added to the treemap.
1 apple
1 orange
3 pear
3 pineapple
4 dragonfruit
my code:
public class Treemap {
private List<String> fList = new ArrayList<String>();
private TreeMap<Integer, List<String>> tMap = new TreeMap<Integer, List<String>>();
public static void main(String[] args) {
Treemap tm = new Treemap();
String file = "";
if (args.length == 1) {
file = args[0];
try {
tm.Read(file);
} catch (IOException ex) {
System.out.println("Error");
}
} else {
System.out.println("Usage: java treemap 'Filename'");
System.exit(1);
}
}
public void Read(String file) throws IOException {
//Scanner in = null;
BufferedReader in = null;
InputStream fis;
try {
fis = new FileInputStream(file);
in = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = in.readLine()) != null) {
String[] file_Array = line.split(" ", 2);
if (file_Array[0].equalsIgnoreCase("1")) {
Add(Integer.parseInt(file_Array[0]), file_Array[1]);
Display(1);
} else if (file_Array[0].equalsIgnoreCase("3")) {
Add(Integer.parseInt(file_Array[0]), file_Array[1]);
Display(3);
} else if (file_Array[0].equalsIgnoreCase("4")) {
Add(Integer.parseInt(file_Array[0]), file_Array[1]);
Display(4);
}
}
} catch (IOException ex) {
System.out.println("Input file " + file + " not found");
System.exit(1);
} finally {
in.close();
}
}
public void Add(int item, String fruit) {
if (tMap.containsKey(item) == false) {
tMap.put(item, fList);
fList.add(fruit);
System.out.println("Fruits added " + item);
} else {
System.out.println("not exist");
}
}
public void Display(int item) {
if (tMap.containsKey(item)) {
System.out.print("Number " + item + ":" + "\n");
System.out.print(fList);
System.out.print("\n");
} else {
System.out.print(item + " WAS NOT FOUND"+ "\n");
}
}
}
ideal output
Number 1:
[apple, orange]
Number 3:
[pear, pineapple]
Number 4:
[dragonfruit]
currently i only able to output this
Fruits added 1
Number 1:
[apple]
not exist
Number 1:
[apple]
Fruits added 3
Number 3:
[apple, pear]
not exist
Number 3:
[apple, pear]
Fruits added 4
Number 4:
[apple, pear, dragonfruit]
How should I display the item following by the list of fruit added to that number?
Try this code. Its working. By the way you should improve this code. The code is not optimised.
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
public class Treemap {
private List<String> fList = new ArrayList<String>();
private TreeMap<Integer, List<String>> tMap = new TreeMap<Integer, List<String>>();
public static void main(String[] args) {
Treemap tm = new Treemap();
String file = "";
if (args.length == 1) {
file = args[0];
try {
tm.Read(file);
} catch (IOException ex) {
System.out.println("Error");
}
} else {
System.out.println("Usage: java treemap 'Filename'");
System.exit(1);
}
}
public void Read(String file) throws IOException {
//Scanner in = null;
BufferedReader in = null;
InputStream fis;
try {
fis = new FileInputStream(file);
in = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = in.readLine()) != null) {
String[] file_Array = line.split(" ", 2);
if (file_Array[0].equalsIgnoreCase("1")) {
Add(Integer.parseInt(file_Array[0]), file_Array[1]);
// Display(1);
} else if (file_Array[0].equalsIgnoreCase("3")) {
Add(Integer.parseInt(file_Array[0]), file_Array[1]);
// Display(3);
} else if (file_Array[0].equalsIgnoreCase("4")) {
Add(Integer.parseInt(file_Array[0]), file_Array[1]);
// Display(4);
}
}
} catch (IOException ex) {
System.out.println("Input file " + file + " not found");
System.exit(1);
} finally {
for(int i: tMap.keySet())
Display(i);
in.close();
}
}
public void Add(int item, String fruit) {
if (tMap.containsKey(item) == false) {
fList = new ArrayList<>();
fList.add(fruit);
tMap.put(item, fList);
// System.out.println("Fruits added " + item);
} else {
tMap.get(item).add(fruit);
// System.out.println("not exist");
}
}
public void Display(int item) {
if (tMap.containsKey(item)) {
System.out.print("Number " + item + ":" + "\n");
System.out.print(tMap.get(item));
System.out.print("\n");
} else {
System.out.print(item + " WAS NOT FOUND"+ "\n");
}
}
}
Here is your READ , ADD ad DISPLAY method,
public void Read(String file) throws IOException {
BufferedReader in = null;
InputStream fis;
try {
fis = new FileInputStream(file);
in = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = in.readLine()) != null) {
String[] file_Array = line.split(" ", 2);
Add(Integer.parseInt(file_Array[0]),file_Array[1]);
}
Display(-1); // -1 for displaying all
} catch (IOException ex) {
System.out.println("Input file " + file + " not found");
System.exit(1);
} finally {
in.close();
}
}
public void Add(int item, String fruit) {
if (tMap.containsKey(item)) {
fList = tMap.get(item);
} else {
fList = new ArrayList<String>();
}
fList.add(fruit);
tMap.put(item, fList);
}
public void Display(int key) {
if(key == -1){
for (Map.Entry<Integer, List<String>> entry : tMap.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}else{
System.out.println(key);
System.out.println(tMap.get(key));
}
}
You make unnecessary complicated your code. Try with simple code.
public class Treemap {
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(new File("file.txt"));
Map<Integer, List<String>> tMap = new TreeMap<>();
while (sc.hasNextLine()) {
String line = sc.nextLine();
String[] values=line.split(" ");
List<String> fList;
Integer key=Integer.valueOf(values[0]);
if(tMap.containsKey(key)){//Key already inserted
fList=tMap.get(key); //Get existing List of key
fList.add(values[1]);
}
else{
fList = new ArrayList<String>();
fList.add(values[1]);
tMap.put(key, fList);
}
}
for (Map.Entry<Integer, List<String>> entry : tMap.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
}
}
Output:
1
[apple, orange]
3
[pear, pineapple]
4
[dragonfruit]
Change some code for the method Add(), which is incorrect in your code.
What if the Map contains the key?
Following code is modified based on your code, hope this can help you some.
public void Add(int item, String fruit) {
if (tMap.containsKey(item)==false) {
fList.clear();
fList.add(fruit);
tMap.put(item, fList);
System.out.println("Fruits added " + item);
} else {
tMap.get(item).add(fruit);
}
}
I work at a printing company that has many programs in COBOL and I have been tasked to
convert the COBOL programs into JAVA programs. I've run into a snag in the one conversion. I need to take a file that each line is a record and on each line the data is blocked.
Example of a line is
60000003448595072410013 FFFFFFFFFFV 80 0001438001000014530020120808060134
I need to sort data by a 5 digit number at the 19-23 characters and then by the very first character on a line.
BufferedReader input;
BufferedWriter output;
String[] sort, sorted, style, accountNumber, customerNumber;
String holder;
int lineCount;
int lineCounter() {
int result = 0;
boolean eof = false;
try {
FileReader inputFile = new FileReader("C:\\Users\\cbook\\Desktop\\Chemical\\"
+ "LB26529.fil");
input = new BufferedReader(inputFile);
while (!eof) {
holder = input.readLine();
if (holder == null) {
eof = true;
} else {
result++;
}
}
} catch (IOException e) {
System.out.println("Error - " + e.toString());
}
return result;
}
chemSort(){
lineCount = this.lineCounter();
sort = new String[lineCount];
sorted = new String[lineCount];
style = new String[lineCount];
accountNumber = new String[lineCount];
customerNumber = new String[lineCount];
try {
FileReader inputFile = new FileReader("C:\\Users\\cbook\\Desktop\\Chemical\\"
+ "LB26529.fil");
input = new BufferedReader(inputFile);
for (int i = 0; i < (lineCount + 1); i++) {
holder = input.readLine();
if (holder != null) {
sort[i] = holder;
style[i] = sort[i].substring(0, 1);
customerNumber[i] = sort[i].substring(252, 257);
}
}
} catch (IOException e) {
System.out.println("Error - " + e.toString());
}
}
This what I have so far and I'm not really sure where to go from here or even if this is the correct way
to go about sorting the file. After the file is sorted it will be stored into another file and processed
again with another program for it to be ready for printing.
List<String> linesAsList = new ArrayList<String>();
String line=null;
while(null!=(line=reader.readLine())) linesAsList.add(line);
Collections.sort(linesAsList, new Comparator<String>() {
public int compare(String o1,String o2){
return (o1.substring(18,23)+o1.substring(0,1)).compareTo(o2.substring(18,23)+o2.substring(0,1));
}});
for (String line:linesAsList) System.out.println(line); // or whatever output stream you want
This phone's autocorrect is messing up my answer
Read the file into an ArrayList (instead of an array). Use the following methods:
// to declare the arraylist
ArrayList<String> lines = new ArrayList<String>();
// to add a new line to it (within your reading-lines loop)
lines.add(input.readLine());
Then, sort it using a custom Comparator:
Collections.sort(lines, new Comparator<String>() {
public int compare(String a, String b) {
String a5 = theFiveNumbersOf(a);
String b5 = theFiveNumbersOf(b);
int firstComparison = a5.compareTo(b5);
if (firstComparison != 0) { return firstComparison; }
String a1 = theDigitOf(a);
String b1 = theDigitOf(b);
return a1.compareTo(b1);
}
});
(It is unclear what 5 digits or what digit you want to compare; I've left them as functions for you to fill in).
Finally, write it to the output file:
BufferedWriter ow = new BufferedWriter(new FileOutputStream("filename.extension"));
for (String line : lines) {
ow.println(line);
}
ow.close();
(adding imports and try/catch as needed)
This code will sort a file based on mainframe sort parameters.
You pass 3 parameters to the main method of the Sort class.
The input file path.
The output file path.
The sort parameters in mainframe sort format. In your case, this string would be 19,5,CH,A,1,1,CH,A
This first class, the SortParameter class, holds instances of the sort parameters. There's one instance for every group of 4 parameters in the sort parameters string. This class is a basic getter / setter class, except for the getDifference method. The getDifference method brings some of the sort comparator code into the SortParameter class to simplify the comparator code in the Sort class.
public class SortParameter {
protected int fieldStartByte;
protected int fieldLength;
protected String fieldType;
protected String sortDirection;
public SortParameter(int fieldStartByte, int fieldLength, String fieldType,
String sortDirection) {
this.fieldStartByte = fieldStartByte;
this.fieldLength = fieldLength;
this.fieldType = fieldType;
this.sortDirection = sortDirection;
}
public int getFieldStartPosition() {
return fieldStartByte - 1;
}
public int getFieldEndPosition() {
return getFieldStartPosition() + fieldLength;
}
public String getFieldType() {
return fieldType;
}
public String getSortDirection() {
return sortDirection;
}
public int getDifference(String a, String b) {
int difference = 0;
if (getFieldType().equals("CH")) {
String as = a.substring(getFieldStartPosition(),
getFieldEndPosition());
String bs = b.substring(getFieldStartPosition(),
getFieldEndPosition());
difference = as.compareTo(bs);
if (getSortDirection().equals("D")) {
difference = -difference;
}
}
return difference;
}
}
The Sort class contains the code to read the input file, sort the input file, and write the output file. This class could probably use some more error checking.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Sort implements Runnable {
protected List<String> lines;
protected String inputFilePath;
protected String outputFilePath;
protected String sortParameters;
public Sort(String inputFilePath, String outputFilePath,
String sortParameters) {
this.inputFilePath = inputFilePath;
this.outputFilePath = outputFilePath;
this.sortParameters = sortParameters;
}
#Override
public void run() {
List<SortParameter> parameters = parseParameters(sortParameters);
lines = read(inputFilePath);
lines = sort(lines, parameters);
write(outputFilePath, lines);
}
protected List<SortParameter> parseParameters(String sortParameters) {
List<SortParameter> parameters = new ArrayList<SortParameter>();
String[] field = sortParameters.split(",");
for (int i = 0; i < field.length; i += 4) {
SortParameter parameter = new SortParameter(
Integer.parseInt(field[i]), Integer.parseInt(field[i + 1]),
field[i + 2], field[i + 3]);
parameters.add(parameter);
}
return parameters;
}
protected List<String> sort(List<String> lines,
final List<SortParameter> parameters) {
Collections.sort(lines, new Comparator<String>() {
#Override
public int compare(String a, String b) {
for (SortParameter parameter : parameters) {
int difference = parameter.getDifference(a, b);
if (difference != 0) {
return difference;
}
}
return 0;
}
});
return lines;
}
protected List<String> read(String filePath) {
List<String> lines = new ArrayList<String>();
BufferedReader reader = null;
try {
String line;
reader = new BufferedReader(new FileReader(filePath));
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return lines;
}
protected void write(String filePath, List<String> lines) {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(filePath));
for (String line : lines) {
writer.write(line);
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.flush();
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
if (args.length < 3) {
System.err.println("The sort process requires 3 parameters.");
System.err.println(" 1. The input file path.");
System.err.println(" 2. The output file path.");
System.err.print (" 3. The sort parameters in mainframe ");
System.err.println("sort format. Example: 15,5,CH,A");
} else {
new Sort(args[0], args[1], args[2]).run();
}
}
}
I am writing an app for Android that grabs meta data from SHOUTcast mp3 streams. I am using a pretty nifty class I found online that I slightly modified, but I am still having 2 problems.
1) I have to continuously ping the server to update the metadata using a TimerTask. I am not fond of this approach but it was all I could think of.
2) There is a metric tonne of garbage collection while my app is running. Removing the TimerTask got rid of the garbage collection issue so I am not sure if I am just doing it wrong or if this is normal.
Here is the class I am using:
public class IcyStreamMeta {
protected URL streamUrl;
private Map<String, String> metadata;
private boolean isError;
public IcyStreamMeta(URL streamUrl) {
setStreamUrl(streamUrl);
isError = false;
}
/**
* Get artist using stream's title
*
* #return String
* #throws IOException
*/
public String getArtist() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
try {
String streamTitle = data.get("StreamTitle");
String title = streamTitle.substring(0, streamTitle.indexOf("-"));
return title.trim();
}catch (StringIndexOutOfBoundsException e) {
return "";
}
}
/**
* Get title using stream's title
*
* #return String
* #throws IOException
*/
public String getTitle() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
try {
String streamTitle = data.get("StreamTitle");
String artist = streamTitle.substring(streamTitle.indexOf("-")+1);
return artist.trim();
} catch (StringIndexOutOfBoundsException e) {
return "";
}
}
public Map<String, String> getMetadata() throws IOException {
if (metadata == null) {
refreshMeta();
}
return metadata;
}
public void refreshMeta() throws IOException {
retreiveMetadata();
}
private void retreiveMetadata() throws IOException {
URLConnection con = streamUrl.openConnection();
con.setRequestProperty("Icy-MetaData", "1");
con.setRequestProperty("Connection", "close");
//con.setRequestProperty("Accept", null);
con.connect();
int metaDataOffset = 0;
Map<String, List<String>> headers = con.getHeaderFields();
InputStream stream = con.getInputStream();
if (headers.containsKey("icy-metaint")) {
// Headers are sent via HTTP
metaDataOffset = Integer.parseInt(headers.get("icy-metaint").get(0));
} else {
// Headers are sent within a stream
StringBuilder strHeaders = new StringBuilder();
char c;
while ((c = (char)stream.read()) != -1) {
strHeaders.append(c);
if (strHeaders.length() > 5 && (strHeaders.substring((strHeaders.length() - 4), strHeaders.length()).equals("\r\n\r\n"))) {
// end of headers
break;
}
}
// Match headers to get metadata offset within a stream
Pattern p = Pattern.compile("\\r\\n(icy-metaint):\\s*(.*)\\r\\n");
Matcher m = p.matcher(strHeaders.toString());
if (m.find()) {
metaDataOffset = Integer.parseInt(m.group(2));
}
}
// In case no data was sent
if (metaDataOffset == 0) {
isError = true;
return;
}
// Read metadata
int b;
int count = 0;
int metaDataLength = 4080; // 4080 is the max length
boolean inData = false;
StringBuilder metaData = new StringBuilder();
// Stream position should be either at the beginning or right after headers
while ((b = stream.read()) != -1) {
count++;
// Length of the metadata
if (count == metaDataOffset + 1) {
metaDataLength = b * 16;
}
if (count > metaDataOffset + 1 && count < (metaDataOffset + metaDataLength)) {
inData = true;
} else {
inData = false;
}
if (inData) {
if (b != 0) {
metaData.append((char)b);
}
}
if (count > (metaDataOffset + metaDataLength)) {
break;
}
}
// Set the data
metadata = IcyStreamMeta.parseMetadata(metaData.toString());
// Close
stream.close();
}
public boolean isError() {
return isError;
}
public URL getStreamUrl() {
return streamUrl;
}
public void setStreamUrl(URL streamUrl) {
this.metadata = null;
this.streamUrl = streamUrl;
this.isError = false;
}
public static Map<String, String> parseMetadata(String metaString) {
Map<String, String> metadata = new HashMap<String, String>();
String[] metaParts = metaString.split(";");
Pattern p = Pattern.compile("^([a-zA-Z]+)=\\'([^\\']*)\\'$");
Matcher m;
for (int i = 0; i < metaParts.length; i++) {
m = p.matcher(metaParts[i]);
if (m.find()) {
metadata.put((String)m.group(1), (String)m.group(2));
}
}
return metadata;
}
}
And here is my timer:
private void getMeta() {
timer.schedule(new TimerTask() {
public void run() {
try {
icy = new IcyStreamMeta(new URL(stationUrl));
runOnUiThread(new Runnable() {
public void run() {
try {
artist.setText(icy.getArtist());
title.setText(icy.getTitle());
} catch (IOException e) {
e.printStackTrace();
} catch (StringIndexOutOfBoundsException e) {
e.printStackTrace();
}
}
});
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
},0,5000);
}
Much appreciation for any assistance!
I've replaced the IcyStreamMeta class in my program and am getting the meta data from the 7.html file that is a part of the SHOUTcast spec. Far less data usage and all that so I feel it is a better option.
I am still using the TimerTask, which is acceptable. There is practically no GC any more and I am happy with using 7.html and a little regex. :)