I have an string array of text file names. I would like to send this string array through an iterator and have it give me the first X number of characters of each text file. It would then put those strings in to an array that I can include in a list view.
I was planning on using a buffered reader to read the text and then substring it. But as for using the loops to go through each file, I am guessing that you would need to use a for loop or a foreach loop. However I am really unknowledgeable about how to use those.
Any help would be appreciated. Thanks!
Edit:
I should have added this earlier. I am using this to show what files have been downloaded and also to give them a preview of the text file. However, like I said above, some of them have not been downloaded. I would like to know which position in the filename array actually exist and to be able to put the retrieved strings in the proper places of the list view. Will this affect any of the current answers? Any ideas?
Let's name the variables you have:
String array: String filenames[]
x number of chars: int x
array of x chars in file: string chars[]. Assume you set each index to empty string.
import java.util.Scanner
public static void main(String[] args) {
Scanner fin = null;
// Loop through files
for(int i = 0; i < filenames.length; i++) {
// Open the file with a FileReader
fin = new Scanner(new BufferedReader(new FileReader(filenames[i])));
// Loop through x chars and add to string
for(int j = 0; j < x && fin.hasNext(); j++) {
chars[i] += fin.next();
}
// Close your file
fin.close();
}
}
Thanks for your help. This is what I ended up going with:
filenamearray = filenamefinal.split(";");
try {
List<String> results = new ArrayList<String>();
for (int i = 0; i < filenamearray.length; i++) {
File txt = new File(getExternalFilesDir(Environment.DIRECTORY_MUSIC) + "/" + filenamearray[i] + ".txt");
if (txt.exists()) {
txtread = new FileInputStream(getExternalFilesDir(Environment.DIRECTORY_MUSIC) + "/" + filenamearray[i] + ".txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(txtread));
String text = reader.readLine();
displaytxt = text.substring(0, 45) + ". . ."
results.add(displaytxt);
} else {
results.add("empty");
}
}
finalversetextarray = new String[results.size()];
finalversetextarray = results.toArray(finalversetextarray);
Related
I'm trying to create a class that uses a separate method to read and store two sets of data from a file into 2 different arrays. I don't know if it's the read method or my output that is incorrect but I can't seem to figure out how to have it printout all data sets. I get the last line of the file instead of all content.
examples from products.txt are
Product1,1100
Product2,1205
Product3,1000
Main Method
String[] pName;
double[] pPrice;
String outputStr = null;
int i = 0;
//String name = null;
// Input number of customers
//initialize arrays with size
pPrice=new double[50];
pName=new String[50];
// read from file, the method is incomplete
try {
readFromFile(pName, pPrice, "products.txt");
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "File cannot be read");
e.printStackTrace();
}
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
// Call method before sorting both arrays
display(outputStr);
Reading Method
public static void readFromFile(String[] pName, double[] pPrice, String fileName) throws FileNotFoundException {
// read data from products
// Create a File instance
File file = new File(fileName);
// Create a Scanner for the file
Scanner sc = new Scanner(file);
// Read data from a file, the data fields are separated by ','
// Change the Scanner default delimiter to ','
sc.useDelimiter(",|\r\n");
// Start reading data from file using while loop
int i = 0;
while (sc.hasNext()) {
String name = sc.next();
String cost = sc.next();
//add the customer data through arrays
pName[i] = name;
pPrice[i] = Double.parseDouble(cost);
i++;
}//end while
// Close the file
The problem is that your for loop assigns every line to the outputStr variable:
for (i = 0; i < pName.length; i++) {
outputStr = pName[i] + "," + pPrice[i] + "\n";
}
Seeing your linefeed in the end I assume you want to concatenate all lines into that string variable. So change that code into
for (i = 0; i < pName.length; i++) {
outputStr += pName[i] + "," + pPrice[i] + "\n";
}
As you initialize the variable to be null this may throw a NullPointerException. If that is the case, simply initialize with "".
For my Java class, I'm working on a project that is essentially a database for MTG cards. I have to read from a file as part of the project, so I am reading the card information from a file, and then splitting the lines to put each different type of information together to form different object classes for the different types of cards. The main nitpicky issue I'm running into right now is that I need the card text to be on one line in the text file so I can read it line by line, but I'd prefer if it weren't all on one line when I print it to the console. Is there any way to add a character combination into the text of the file itself that will tell my compiler, "line break here," when it reads that, or am I out of luck? I know I could just use \n in the code to achieve this, but as I am looping through the file, there is no way to do so properly that I know of, as not every card's text needs line breaks inserted. If it matters, this is the chunk of my code that deals with that:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Scanner;
public class MTG {
public static void main(String[] args) {
int creatureLength = 4;
//Prompt User
Scanner sc = new Scanner(System.in);
System.out.println("Welcome to the Magic: the Gathering card database. This tool currently supports Rare and Mythic Rare cards from the Throne of Eldraine Expansion.");
try {
System.out.println("\nSelect the card type you'd like to view.");
System.out.println(""
+ "(1)Creatures\n"
);
int choice = Integer.parseInt(sc.next());
//Choose type
//Creatures
if(choice == 1){
Creature[] creatures = creatureGen("textfiles/Creatures.txt", creatureLength);
System.out.println("\nViewing creatures. Which card would you like to view?: \n");
for(int k = 0; k < creatureLength; k++) {
System.out.println(
"(" + (k + 1) + ") " + creatures[k].getName());
}
int creatureChoice = Integer.parseInt(sc.next());
try {
System.out.println("\n" + creatures[(creatureChoice - 1)]);}
catch(Exception e) {
System.out.println("Input was not a specified number. Exiting...");
}
}
}
catch(NumberFormatException ex){
System.out.println("Input was not a specified number. Exiting...");
}
sc.close();
}
//Read Creature text file
public static Creature[] creatureGen(String path, int length) {
Creature[] creatures = new Creature[length];
try {
FileReader file = new FileReader(path);
BufferedReader reader = new BufferedReader(file);
String name[] = new String[length];
String cost[] = new String[length];
String color[] = new String[length];
String type[] = new String[length];
String cTypes[] = new String[length];
String tags[] = new String[length];
String text[] = new String[length];
int power[] = new int[length];
int toughness[] = new int[length];
for (int i = 0; i < length; i++) {
String line = reader.readLine();
if(line != null) {
name[i] = line.split("\\|")[0];
cost[i] = line.split("\\|")[1];
color[i] = line.split("\\|")[2];
type[i] = line.split("\\|")[3];
cTypes[i] = line.split("\\|")[4];
tags[i] = line.split("\\|")[5];
text[i] = line.split("\\|")[6];
power[i] = Integer.parseInt(line.split("\\|")[7]);
toughness[i] = Integer.parseInt(line.split("\\|")[8]);
creatures[i] = new Creature(name[i], cost[i], color[i], type[i], cTypes[i], tags[i], text[i], power[i], toughness[i]);
}
}
reader.close();
}
catch (Exception e) {
System.out.println("Error reading file: " + path);
}
return creatures;
}
}
The Creature object class essentially just stores the data that I am putting into it with the creatureGen method. A sample line from the text file I am reading from looks something like this:
Charming Prince|1W|White|Creature|Human Noble||When Charming Prince enters the battlefield, choose one — • Scry 2. • You gain 3 life. • Exile another target creature you own. Return it to the battlefield under your control at the beginning of the next end step.|2|2
It would be ideal to be able to insert line breaks after each of the bullet points in this card, for example, but as I said earlier, I need the text to be in one line for my loop to read it. Is there any way around this when I print this back to the console? I appreciate any help.
Just replace those bullet points with line breaks :
text[i] = line.split("\\|")[6].replaceAll("•","\n");
Also, you should not split each time you need an element, put the result of line.split("\|") in a String[] variable and use it afterwards.
for (int i = 0; i < length; i++) {
String line = reader.readLine();
if(line != null) {
String[] elements = line.split("\\|");
name[i] = elements[0];
cost[i] = elements[1];
color[i] = elements[2];
type[i] = elements3];
cTypes[i] = elements[4];
tags[i] = elements[5];
text[i] = elements[6].replaceAll("•","\n");
power[i] = Integer.parseInt(elements[7]);
toughness[i] = Integer.parseInt(elements[8]);
creatures[i] = new Creature(name[i], cost[i], color[i], type[i], cTypes[i], tags[i], text[i], power[i], toughness[i]);
}
}
Finally, about vocabulary, the compiler is not reading your file. The compiler translates your code into binary instructions for the processor (to summarize).
Your file is read at runtime.
I want to read a csv File and put words " Jakarta " and " Bandung " in a combobox. Here's the input
id,from,
1,Jakarta
2,Jakarta
5,Jakarta
6,Jakarta
10,Bandung
11,Bandung
12,Bandung
I managed to get the words and put it in the combobox, but as you can see, the text file itself contains a lot word " Jakarta " and " Bandung " while i want to show both only once in the combobox.
Here's my temporary code, which works for now but inefficient and probably can't be used if the word has more variety
public String location;
private void formWindowOpened(java.awt.event.WindowEvent evt) {
String csvFile = "C:\\Users\\USER\\Desktop\\Project Data.csv";
BufferedReader br = null;
LineNumberReader reader = null;
String line = "";
String cvsSplitBy = "-|\\,";
br = new BufferedReader(new FileReader(csvFile));
reader = new LineNumberReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] bookingdata = line.split(cvsSplitBy);
location = bookingdata[1];
ComboBoxModel model = cmb1.getModel();
int size = model.getSize();
cmb1.addItem(location);
for(int i = 1; i < size; i++){
if(model.getElementAt(i).equals("from")){
cmb1.removeItemAt(i);
}
else if(model.getElementAt(i).equals("Bandung")){
cmb1.removeItemAt(i);
}
for(int j = 2; j < i; j++){
if(model.getElementAt(j).equals("Jakarta")){
cmb1.removeItemAt(j);
}
}
}
}
}
Someone else recommended this approach
boolean isEquals = false;
for(i = 0; i < a && !isEquals; i++){
isEquals = location.equals("Jakarta");
if(isEquals){
cmb1.addItem("Jakarta");
}
}
This code doesn't work. As the code doesn't stop once it adds a " Jakarta " but it stops after it completed a loop. thus it still creates duplicate within the combobox.
I would like to know if there's any other code i can try. Thank you
Try putting all the words in a Set first and then add it in the combobox. Set itself will take care of exact one occurrence of each word.
Something like this:
while ((line = br.readLine()) != null) {
// use comma as separator
String[] bookingdata = line.split(cvsSplitBy);
location = bookingdata[1];
ComboBoxModel model = cmb1.getModel();
int size = model.getSize();
// add all location in set and set will only allow distinct values
locationSet.add(location);
}
// after looping through all location put it in combobox
for(String location:locationSet)cmb1.addItem(location);
}
}
As discussed in comments, Sets are meant to keep unique values. Please find the screenshot of JShell below:
PS: This is just to give an idea and may need some amendment as per requirement.
--EDITED--
As discussed, it seems you are still missing something, I tried and write below piece of code and worked fine
package com.digital.core;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JComboBox;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
JFrame jframe = new JFrame();
jframe.setSize(300, 300);
String data = "id,from,\n" +
"1,Jakarta\n" +
"2,Jakarta\n" +
"5,Jakarta\n" +
"6,Jakarta\n" +
"10,Bandung\n" +
"11,Bandung\n" +
"12,Bandung";
String[] dataArr = data.split("\n");
Set<String> locationSet = new HashSet<>();
for(String line:dataArr) {
locationSet.add(line.split(",")[1]);
}
JComboBox<String> comboBox = new JComboBox<>();
for(String location:locationSet)
comboBox.addItem(location);
jframe.add(comboBox);
jframe.setVisible(true);
}
}
You could create an ObservablArrayList of strings and as you read the CSV file, check if the list already contains that string:
ObservableList<String> locationsList = FXCollections.observableArrayList();
// Add your strings to the array as they're loaded, but check to
// make sure the string does not already exist
if (!locationsList.contains(location)) {
locationsList.add(location);
}
Then, after reading the whole file and populating the list, just set the items in your combobox to that ObservableArrayList.
I have a Jtable which displays the following when triggered.
How can I write all the contents of it to a Text File while keeping its original format. The Text File should look something like this.
Line Number Error Solution Percentage(%)
6 in int 33%
This is what I tried so far. But only value 6 is being written to the file. Any Help.
My codes(only the main parts):
private static final String[] columnNames = {"Line Number", "Error","Solution","Percentage (%)"};
static DefaultTableModel model = new DefaultTableModel(null,columnNames);
public static void DisplayMyJList(List<CaptureErrors> x) throws IOException
{
String [] myErrorDetails = new String[x.size()];
int i = 0;
int line,percentage;
String err, sol;
String aLine;
StringBuffer fileContent = new StringBuffer();
for(CaptureErrors e: x)
{
Vector row = new Vector();
row.add(e.getLinenumber());
row.add(e.getMyfounderror());
row.add(e.getMycorrection());
row.add(e.getMyPercentage()+"%");
model.addRow( row );
for (int i1 = 0; i1 < model.getRowCount(); i1++) {
Object cellValue = model.getValueAt(i1, 0);
// ... continue to read each cell in a row
fileContent.append(cellValue);
// ... continue to append each cell value
FileWriter fileWriter = new FileWriter(new File("C:\\Users\\Antish\\Desktop\\data.txt"));
fileWriter.write(fileContent.toString());
fileWriter.flush();
fileWriter.close();
}
Update I tried this with 2 loops and it gives me the following. I lost the original Format:
Code:
String separator = System.getProperty( "line.separator" );
try
{
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file,true));
PrintWriter fileWriter = new PrintWriter(bufferedWriter);
for(int i1=0; i1<model.getRowCount(); ++i1)
{
for(int j=0; j<model.getColumnCount(); ++j)
{ String names = columnNames[counter];
String s = model.getValueAt(i1,j).toString();
fileWriter.print(names +" ");
fileWriter.append( separator );
fileWriter.print(s + " ");
counter ++;
}
fileWriter.println("");
}
fileWriter.close();
}catch(Exception e)
{
Your code isn't complete but I can see 1, maybe 2 errors:
1) You need a double loop, one for the rows and then a second for every column in the row. The code you posted only shows you getting the value from the first column which would explain why you only see "6".
2) The code to write to the file needs to be outside your two loops. The way the code is written now you will recreate a new file for every row, which mean you will only ever have a single row of data in the file
I have a similar problem.This is a snippet of my source:
FileWriter fstream = new FileWriter("results_for_excel.txt");
BufferedWriter writer = new BufferedWriter(fstream);
String sourceDirectory = "CVs";
File f = new File(sourceDirectory);
String[] filenames = f.list();
Arrays.sort(filenames);
String[] res = new String[filenames.length];
for (int i = 0; i < filenames.length; i++) {
System.out.println((i + 1) + " " + filenames[i]);
}
for (int i = 0; i < filenames.length; i++) {
int beg = filenames[i].indexOf("-");
int end = filenames[i].indexOf(".");
res[i] = filenames[i].substring(beg,end);
System.out.println((i+1)+res[i]);
writer.write(res[i] + "\n");
}
writer.flush();
writer.close();
I get an exception at res[i] = filenames[i].substring(beg,end);
I cant figure what's going on.Thanks in advance:)
P.S I have read all the duplicates but nothing happened:(
Add the following code after
int beg = filenames[i].indexOf("-");
int end = filenames[i].indexOf(".");
This will display the filename that is in the wrong format;
if (beg == -1 || end == -1)
{
System.out.println("Bad filename: " + filenames[i]);
}
The error occurs, because a filename does not contain both '-' and '.'. In that case indexOf returns -1 which is not a valid parameter for substring.
Either beg or end is -1. This means the filename doesn't contain - or .. Simple as that:)
Either
int beg = filenames[i].indexOf("-");
int end = filenames[i].indexOf(".");
is returning a -1, its possible there's a file which doesn't contain either.
One of characters in this code
int beg = filenames[i].indexOf("-");
int end = filenames[i].indexOf(".");
is not found, so either beg or end equals -1. That's why you got the exception while calling substring with negative arguments.
The problem was at a KDE file called ".directory".Thank you very very much all of you:)