Change delimiter in OpenCSV CSVReader - java

I have the following piece of code which reads a CSV file.
public class TestMain {
public static void parseTsv(String filePath) throws Exception {
try (CSVReader reader = new CSVReader(new InputStreamReader(Objects.requireNonNull(TestMain.class.getResourceAsStream(filePath))))) {
String[] line;
while ((line = reader.readNext()) != null) {
System.out.println(line[0] + " " + line[1]);
}
}
}
public static void main(String[] args) {
try {
parseTsv("path-to-tsv-file");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
And I want to modify the delimiter so that it can read tsv files (tab-separated). Any help would be greatly appreciated!

With g00se's help, please see below the correct code:
public class TestMain {
public static void parseTsv(String filePath) throws Exception {
try (CSVReader reader = new CSVReaderBuilder(new InputStreamReader(Objects.requireNonNull(TestMain.class.getResourceAsStream(filePath))))
.withCSVParser(new CSVParserBuilder().withSeparator('\t').build())
.build()) {
String[] line;
while ((line = reader.readNext()) != null) {
System.out.println(line[0] + " " + line[1]);
}
}
}
public static void main(String[] args) {
try {
parseTsv("path-to-tsv-file");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

Related

How to store default constructor output in string?

public class demo2{
public demo2() throws FileNotFoundException {
Scanner scanner = new Scanner(new
File("/home/madhu/Desktop/demo.txt"));
while (scanner.hasNextLine())
System.out.println(scanner.nextLine());
}
public static void main(String[] args) throws FileNotFoundException {
demo2 obj = new demo2();
}
}
new demo2()
gives output as
Data1,200,1000
Data2,201,2000
How to store new demo2() value into String array or how to write to get output in such format ?
I want to store as
st1= Data1,200,1000
st2= Data2,201,2000
You could do something like this.
ScannerReader.class
public class ScannerReader {
private ArrayList<String> scannerInput;
public ScannerReader() {
scannerInput = new ArrayList<>();
readFileInput();
}
private void readFileInput() {
try {
Scanner scanner = new Scanner(new File("src\\date.txt"));
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
scannerInput.add(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void printArrayData() {
for(String line : scannerInput) {
System.out.println(line);
}
}
}
Main.class
public class Main {
public static void main(String[] args) {
ScannerReader reader = new ScannerReader();
reader.printArrayData();
}
}

Read file with multiple threads

Is it possible to read a text file by running several threads, so that received line contains information about the thread that read this line?
For now, i can read with one thread:
public class Test {
public static void main(String[] args) throws InterruptedException {
Deque<String> deque = new LinkedList<>();
for (int i = 0; i < 4; i++) {
new Thread(new SubReadThread(deque)).start();
}
new Thread(new WriteThread(deque)).start();
}
}
class SubReadThread implements Runnable {
private final Deque<String> deque;
public SubReadThread(Deque<String> deque) {
this.deque = deque;
}
#Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("list.txt"), "UTF8"));
String line = null;
String newLine;
while (true) {
synchronized (deque) {
if (deque.size() < 1) {
line = br.readLine();
newLine = "#" + (Thread.currentThread().getId() - 9) + " " + line;
deque.addLast(newLine);
deque.notify();
} else {
deque.wait();
}
if (line == null) {
break;
}
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
class WriteThread implements Runnable {
private final Deque<String> deque;
private List<String> list = new ArrayList<>();
public WriteThread(Deque<String> deque) {
this.deque = deque;
}
#Override
public void run() {
String line;
while (true) {
synchronized (deque) {
if (deque.size() > 0) {
if ((line = deque.pollFirst()).contains("null")) {
break;
} else {
list.add(line);
deque.notifyAll();
}
} else {
try {
deque.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
for(String s : list) {
System.out.println(s);
}
}
}
And expected output something like this:
#3 line1
#1 line2
#4 line3
#2 line4
...............
UPDATE All that was needed to work properly, move BufferedReader to main method and pass its object to the constructor.

Proper way to use Generics in this example?

FileReader fileReader = null;
Object reader = null;
String dataRow = null;
fileReader = new FileReader(new File(fileLocation));
if (extension.equals("csv"))
{
reader = new CSVReader(fileReader);
}
else
{
reader = new BufferedReader(fileReader);
}
while (null != (dataRow = reader.readLine()))
{
...
}
The idea is to use different types depending on the file type in order to remove duplicated code. However, I get an error on the last line, since reader is type Object. Thanks for the help.
Maybe you could make 2 methods:
public String read(CSVReader c){
return c.readLine();
}
public String read(BufferedReader br){
return br.readLine();
}
Then, in your current code:
if(extension.equals("csv"))
dataRow = read(new CSVReader(fileReader));
else
dataRow = read(new BufferedReader(fileReader));
This overloading would remove the need for a wrapper class.
If you really want to use a wrapper class, I recommend having this somewhere:
public interface MyIO{
public String readLine();
}
public class MyBr extends BufferedReader implements MyIO{}
public class MyCSV extends CSVReader implements MyIO{}
Then, in your code:
MyIO reader;
if(extension.equals("csv"))
reader = new MyCSV(fileReader);
else
reader = new MyBr(fileReader);
You'd notice that both are the same number of lines of code and (in my opinion) the methods are easier to follow.
Just answering to point out that it is certainly possible to use generics even if your types are not cooperative. You'll just have to define specializations for each type separately. I'll just put a sketch in Java 8 here. Not sure what you mean by 'Proper way', there are pros and cons to everything...especially in Java.
Somewhat simpler way, putting generic code in a common superclass:
interface GenericExample {
interface InputGenericCode<Input> {
/**
* This is implemented in subtypes.
*
* #param x
* #return
*/
String readLine(Input x);
default void genericAlgorithm(Input x) {
// algorithm expressed generically here...
for (;;) {
String lineString = readLine(x);
System.out.println("" + lineString);
}
}
}
public class BufferedReaderInputGenericCode implements InputGenericCode<BufferedReader> {
#Override
public String readLine(BufferedReader x) {
try {
return x.readLine();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public class CSVReaderInputGenericCode implements InputGenericCode<CSVReader> {
#Override
public String readLine(CSVReader x) {
return x.readLine();
}
}
static class CSVReader {
public CSVReader(FileReader fileReader) {
throw new RuntimeException("implement this");
}
public String readLine() {
throw new RuntimeException("implement this");
}
}
public static void main(String fileLocation, String extension) {
FileReader fileReader = openFile(fileLocation);
if (extension.equals("csv")) {
CSVReader reader = new CSVReader(fileReader);
new CSVReaderInputGenericCode().genericAlgorithm(reader);
} else {
BufferedReader reader = new BufferedReader(fileReader);
new BufferedReaderInputGenericCode().genericAlgorithm(reader);
}
// dataRow = reader.readLine();
}
public static FileReader openFile(String fileLocation) {
FileReader fileReader = null;
try {
fileReader = new FileReader(new File(fileLocation));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
return fileReader;
}
}
More complex way:
interface GenericExample {
/**
* All generic operations.
*
* #author jonasn
*
* #param <Input>
*/
interface InputGenerics<Input> {
String readLine(Input x);
}
interface InputGenericCode {
public static <Input> void genericAlgorithm(Input x, InputGenerics<Input> generics) {
// algorithm expressed generically here...
for (;;) {
String lineString = generics.readLine(x);
System.out.println("" + lineString);
}
}
}
static class CSVReader {
public CSVReader(FileReader fileReader) {
// TODO Auto-generated constructor stub
}
public String readLine() {
throw new RuntimeException("not implemented");
}
}
public class CSVReaderInputGenerics implements InputGenerics<CSVReader> {
#Override
public String readLine(CSVReader x) {
return x.readLine();
}
}
public class BufferedReaderInputGenerics implements InputGenerics<BufferedReader> {
#Override
public String readLine(BufferedReader x) {
try {
return x.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
}
public static void main(String fileLocation, String extension) {
// String fileLocation = "whatever";
// String extension = "";
FileReader fileReader = null;
// Object reader = null;
String dataRow = null;
try {
fileReader = new FileReader(new File(fileLocation));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
if (extension.equals("csv"))
{
CSVReader reader = new CSVReader(fileReader);
InputGenericCode.genericAlgorithm(reader, new CSVReaderInputGenerics());
}
else
{
BufferedReader reader = new BufferedReader(fileReader);
InputGenericCode.genericAlgorithm(reader, new BufferedReaderInputGenerics());
}
// dataRow = reader.readLine();
}
}

Java run linux(raspbian) command(omxplayer) and get output

I create a program as below to execute a linux (raspbian) command: "omxplayer".
But I don't know why I cannot get output from omxplayer as the time I type it into command line and hit Enter.But the output only show at the end of the video.
So I want to get the output immediately after I type "omxplayer [video_name]" and hit "Enter" in my program.
Just like the command line (terminal) work when I type directly into it in linux.
This is my code:
public class testprog {
public static void main(String args[]) throws IOException {
String in = "";
while(in!="exit")
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
in = reader.readLine();
runCommand(in);
}
}
public static void runCommand(String command)
{
String s;
Process p;
try {
System.out.println("run command " + command);
p = Runtime.getRuntime().exec(new String[]{"bash", "-c",command});
MyInputStreamReader reader1 = new MyInputStreamReader(p.getInputStream());
reader1.setTag("in");
reader1.start();
MyInputStreamReader reader2 = new MyInputStreamReader(p.getErrorStream());
reader2.setTag("in");
reader2.start();
p.waitFor();
System.out.println ("exit: " + p.exitValue());
p.destroy();
} catch (Exception e) {}
}
}
class MyInputStreamReader extends Thread{
boolean isStop = false;
ReadEventHandler handler;
String tag;
InputStream in;
public MyInputStreamReader(InputStream in)
{
this.in = in;
}
public void setHandler(ReadEventHandler handler) {
this.handler = handler;
}
public void setTag(String tag)
{
this.tag = tag;
}
public void run()
{
byte[] buff = new byte[8192];
while (true) {
//String line;
try {
int len = in.read(buff);
if (len == -1)
{
return;
}
String line = new String(buff, 0, len);
if (handler!=null)
handler.onReceived(line);
System.out.println(tag +" " + line);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void dispose()
{
this.isStop = true;
}
public interface ReadEventHandler
{
void onReceived(String line);
}
}
Any response is highly appreciated. Thanks
Did you checked this?
http://javedmandary.blogspot.com/2014/01/firing-up-raspberry-pi-omxplayer-using.html
I guess there is the code you're looking for.

Java reading and writing to same file

I'm using the following code to search specific files in my computer and write the absolute path in a text file. My problem is that every time I run this code it add duplicate lines into text file, i want to add only those lines(file path) which are not written in the text file at that time (no duplicates).. Thank you
public static void walkin(File dir) {
String pattern = ".mp4";
try {
PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter("D:\\nawaaaaaa.txt", true)));
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].isDirectory()) {
walkin(listFile[i]);
} else if (listFile[i].getName().endsWith(pattern)
&& listFile[i].isFile()) {
System.out.println(listFile[i].getPath());
out.write(listFile[i].toString());
out.write("\r\n");
// out.close();
} else {
walkin(listFile[i]);
}
}
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Your code works for me, no idea what is the problem on your side, how you are calling it; but you can optimize your code a bit, something as follows (just very quick code, code be made nicer, but to give you an idea):
public class SomeTest {
private static HashSet<String> filez = new HashSet<String> ();
public static void walkin(File dir, PrintWriter out) {
String pattern = ".mp4";
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].getName().endsWith(pattern) && listFile[i].isFile()) {
//System.out.println(listFile[i].getPath());
if (filez.add(listFile[i].getPath())) {
out.write(listFile[i].toString());
out.write("\r\n");
}
} else {
walkin(listFile[i], out);
}
}
}
}
public static void main(String[] args) {
try {
File dir = new File("C:\\mydir");
PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter("D:\\nawaaaaaa.txt", true)));
walkin(dir, out);
out.close();
} catch (IOException e) {
//
}
}
}
You can use the filez hashset to print stuff, or write your file at the end of the parsing process as well.. your choice.
If you don't want duplicates in the file, you will need to keep track of the file names you have already written. A HashSet<String> is going for this. But I'm surprised the above code works at all given that you keep opening the file at the top of walkin() and walkin() itself is recursive. You need to rethink your code a bit. Possibly passing the PrintWriter into walkin() as a parameter.
Since you are running the code multiple times ("every time I run this code it add duplicate lines into text file"), so once you finish writing to the file, you read each line and store it in a HashSet<String>. And use another writer to write it to the file.
BufferedWriter writer = new BufferedWriter(new FileWriter("filename"));
for (String eachUniqueLine: `Your hash set`) {
writer.write(eachUniqueLine);
writer.newLine();
}
(It is costly as in you have to do more i/o operation)
You need to expand your method into a class that perform this kind of tasks.
You have two main problem you open a writer for each directory and you call the walkin, for things that do not apply to your logic (and open writer again).
You should try to design a class that will be able to create an index for you.
public static void main(String[] args) throws IOException {
File createTempFile = File.createTempFile("mp4", ".idx");
FileIndexer fi = new FileIndexer(createTempFile.getAbsolutePath());
fi.index("C:\\", "mp4");
System.out.println(createTempFile);
}
public static class FileIndexer {
private static final String END_OF_LINE = "\r\n";
private final String outputPath;
private final Set<String> index = new HashSet<String>();
public FileIndexer(String outputPath) {
this.outputPath = outputPath;
}
private boolean isValidPath(String path) {
return outputPath != null && outputPath.trim().length() > 0;
}
private boolean isValidIndexFile(File file) {
return file.isFile() && file.canRead() && file.canWrite();
}
private void createIndexFile(File file) throws IOException {
if(file.createNewFile() == false) {
throw new IOException("Could not create index file");
}
this.index.clear();
}
private void readIndexFile(File file) throws IOException {
isValidIndexFile(file);
index.clear();
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new FileReader(file));
String line;
while((line = bufferedReader.readLine()) != null) {
addToIndex(line);
}
} finally {
if(bufferedReader != null) {
bufferedReader.close();
}
}
}
private void addToIndex(String line) {
index.add(line);
}
private PrintWriter openIndex() throws IOException {
if(isValidPath(outputPath) == false) {
throw new IOException(String.format("The outputPath is not valid: [%s]",outputPath));
}
File indexFile = new File(outputPath);
if(indexFile.exists()) {
readIndexFile(indexFile);
} else {
createIndexFile(indexFile);
}
return new PrintWriter(new BufferedWriter(new FileWriter(this.outputPath, true)));
}
public synchronized void index(String pathToIndex, String pattern) throws IOException {
isValidPath(pathToIndex);
PrintWriter out = openIndex();
try {
File elementToIndex = new File(pathToIndex);
index(elementToIndex,pathToIndex, out);
} finally {
if(out != null) {
out.close();
}
}
}
private void index(File elementToIndex, String pattern, PrintWriter out) {
if(elementToIndex == null) {
return;
}
if(elementToIndex.isDirectory()) {
for(File file : elementToIndex.listFiles()) {
index(file,pattern, out);
}
}
if(elementToIndex.isFile() && elementToIndex.getAbsolutePath().endsWith(pattern)) {
writeToIndex(elementToIndex, out);
}
}
private void writeToIndex(File elementToIndex, PrintWriter out) {
out.write(elementToIndex.getAbsolutePath());
out.write(END_OF_LINE);
}
}
Problem Solved (BTW i'm not sure if it is most efficient solution or not ).......
public static void main(String[] args) {
try {
File dir = new File("D:\\To Do");
BufferedWriter out = new BufferedWriter(new FileWriter(
"D:\\path.txt", true));
walkin(dir, out);
out.close();
readfile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // Replace this with a suitable directory
// walkin(new File("D:/to Do"));
}
public static void walkin(File dir, BufferedWriter out) throws IOException {
String pattern = ".mp4";
// BufferedWriter out = new BufferedWriter(
// new FileWriter("D:\\path.txt",true));
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
if (listFile[i].getName().endsWith(pattern)
&& listFile[i].isFile()) {
if (filez.add(listFile[i].getPath())) {
// System.out.println(listFile[i].getPath());
out.write(listFile[i].toString());
out.write("\r\n");
// System.out.println(filez);
}
} else {
walkin(listFile[i], out);
}
}
}
}
public static void readfile() {
BufferedReader br = null;
String str;
try {
BufferedWriter out = new BufferedWriter(new FileWriter(
"D:\\duplicate_free.txt"));
br = new BufferedReader(new FileReader("D:\\path.txt"));
while ((str = br.readLine()) != null) {
if (files.contains(str)) {
} else {
files.add(str);
}
}
for (String uniq : files) {
out.write(uniq);
System.out.println(uniq);
}
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

Categories