Why did this trap in the dead circle? - java

When I try to use FileReader、FileWriter to copy a plain text file, it trapped in a dead circle.That's confused me a lot. I'd appreciate it if someone can help me.
FileReader in = new FileReader("./src/io/copyFile/CopyFileTest01.java");
FileWriter out = new FileWriter("Copy1.java");
char[] chars = new char[1024 * 512]; // once max copy 1MB
When I try to copy file like the followed way,it's ok.
while (true) { // ok
int count = in.read(chars);
System.out.println("count = " + count);
if (count == -1) {
break;
}
out.write(chars, 0, count);
}
However, when I try use the other way, it will trap in the dead circle.
int readCount = 0;
while ((readCount = in.read(chars)) != -1) { // dead circle
System.out.println("readCount = " + readCount);
System.out.println(Arrays.toString(chars)); // bad
out.write(chars, 0, readCount); writing after reading
}
I can't find the reason, and it puzzleed me a lot. I'd appreciate it if someone can help me.
There is the complete code.
package io.copyFile;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
public class CopyFileTest02 {
public static void main(String[] args) {
FileReader in = null;
FileWriter out = null;
try {
in = new FileReader("./src/io/copyFile/CopyFileTest01.java");
out = new FileWriter("Copy1.java");
char[] chars = new char[1024 * 512];
int readCount = 0;
while ((readCount = in.read(chars)) != -1) { // dead
System.out.println("readCount = " + readCount);
System.out.println(Arrays.toString(chars)); // bad
out.write(chars, 0, readCount);
}
// flush
out.flush();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Ok. I found that when remove the followd bolck, this code can work well.However, when I added the followed block, it will never exit the loop.
System.out.println(Arrays.toString(chars));
When I added that Arrays.toString(chars), It will print ',' in console and never stop like the picture.
enter image description here

Related

implement sorting in java for file with records

I asked this question earlier and I forgot to clarify what my question was so hopefully I'm actually clear this time.
I basically need help with sorting a bunch of records in a file based on their number using an algorithm like bubble sort.
I have a file with 5 records where each file consists of a number of integer type and name of 32 characters(each record size should be 36 bytes). I have to store the records into a file. **This is what I need help with:**Then sort the records based on the numbers associated with them, using a sorting algorithm like bubble sort. Another requirement is that when the program sorts the records, it shouldn't read all records in memory at once but move them in the file. For example, after the program reads the first two records, it may switch the records (because 72 > 56) and write them in the same position in the file.
We were provided with the classes to read/write and have random access to the file.
These are the records as they were provided:
72 James
56 Mark
87 John
30 Phillip
44 Andrew
I need to sort these names according to their respective numbers. My question is, what would be the best way to implement this sorting?
Here's the code for the writing class:
package test;
//write to a file
import java.io.*;
class FileWriteStreamTest {
public static void main (String[] args) {
FileWriteStreamTest f = new FileWriteStreamTest();
f.writeMyFile();
}
void writeMyFile() {
DataOutputStream dos = null;
String record = null;
int recCount = 0;
try {
File f = new File("mydata.txt");
if (!f.exists())
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(fos);
dos = new DataOutputStream(bos);
//store records into file
dos.writeBytes(72 + " James \n");
dos.writeBytes(56 + " Mark \n");
dos.writeBytes(87 + " John \n");
dos.writeBytes(30 + " Phillip \n");
dos.writeBytes(44 + " Andrew \n");
} catch (IOException e) {
System.out.println("Uh oh, got an IOException error!" + e.getMessage());
} finally {
// if the file opened okay, make sure we close it
if (dos != null) {
try { dos.close(); }
catch (IOException ioe) { }
}
}
}
}
Here's the code for the reading class:
package test;
//read from a file
import java.io.*;
public class FileReadStreamTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileReadStreamTest f = new FileReadStreamTest();
f.readMyFile();
}
void readMyFile() {
DataInputStream dis = null;
String record = null;
int recCount = 0;
try {
File f = new File("mydata.txt");
if (!f.exists()) {
System.out.println(f.getName() + " does not exist");
return;
}
FileInputStream fis = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(fis);
dis = new DataInputStream(bis);
while ( (record=dis.readLine()) != null ) {
recCount++;
System.out.println(recCount + ": " + record);
}
} catch (IOException e) {
System.out.println("Uh oh, got an IOException error!" + e.getMessage());
} finally {
// if the file opened okay, make sure we close it
if (dis != null) {
try { dis.close(); }
catch (IOException ioe) { }
}
}
}
}
Here's the code for the random access class:
package test;
//read or write to any place in the file
import java.io.*;
class FileRandomAccessTest {
public static void main (String[] args) {
FileRandomAccessTest f = new FileRandomAccessTest();
f.readWriteMyFile();
}
void readWriteMyFile() {
RandomAccessFile raf = null;
String s = null;
try {
File f = new File("mydata.txt");
if (!f.exists()) // check if the file exists
f.createNewFile(); // create a new file
raf = new RandomAccessFile(f, "rw"); // open a file for random access with "r", "rw"
if (raf.length() > 7) {// the size of the file
raf.seek(7); // move the file pointer
System.out.println(raf.readLine()); // read a line from the file pointer
s = raf.readLine();
System.out.println(s);
raf.seek(raf.getFilePointer() - s.length()); // get the file pointer
raf.writeBytes("Test RamdomAccessFile\n"); // write bytes
}
} catch (IOException e) {
System.out.println("Uh oh, got an IOException error!" + e.getMessage());
} finally {
// if the file opened okay, make sure we close it
if (raf != null) {
try { raf.close(); } // close the file
catch (IOException ioe) { }
}
}
}
}
My current bubble sort implementation that needs to be adapted for this problem:
package test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Sort {
public static void bubbleSort(int[] num ) {
int j;
boolean flag = true; // set flag to true to begin first pass
int temp; //holding variable
while ( flag ) {
flag= false; //set flag to false awaiting a possible swap
for( j=0; j < num.length -1; j++ ) {
if ( num[ j ] < num[j+1] ) {
temp = num[ j ]; //swap elements
num[ j ] = num[ j+1 ];
num[ j+1 ] = temp;
flag = true; //shows a swap occurred
}
}
}
}
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File("numbers.txt"));
int [] numbers = new int [5];
int i = 0;
while(scanner.hasNextInt()){
numbers[i++] = scanner.nextInt();
}
bubbleSort(numbers);
System.out.println(Arrays.toString(numbers));
}
}

Counting number of comments in java

I'm developing a tool to analyse and give some statistics about other people's source code, the tool will be able to recognize many things in the code! Right now am stuck at counting the number of comments on the code, my current code is:
public static void main(String[] args) {
String line = "";
int count = 0;
try {
BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
while ((line = br.readLine()) != null) {
if (line.startsWith("//")) {
count++;
} else if (line.startsWith("/*")) {
count++;
while (!(line = br.readLine()).endsWith("'*\'")) {
count++;
break;
}
}
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("count=" + count);
}
To check the code, I am using a test file. But the code is giving me the wrong result in both files, for example; I am getting three in the following file
Yes
//comment
yes
yes
/*
if
random
test
test
*/
While the answer should be two comments!
In the following file, it's showing me that I have five comments while I still actually have two
Yes
//comment
yes
yes
/*
if
random
test
test
/*
*/
The whole approach is flawed. You need to parse the source file properly, at least you need to keep track properly of quotes and nesting of "/*". Note that any comment character combination can appear inside statements like:
System.out.println("// this is *not* a line comment");
String s = "*/ this is not the end of a block comment";
and so on. Then there is the weird behavior with character escape sequences being processed before the file is interpreted:
\u002F* this is a valid comment */
Its not that easy to determine what is a comment and whats not :) I strongly suggest you look for an open source parser solution for java sources.
I think you have a problem in that comments can occur inside or at the end of a line as well...
public static void main(String[] args) {
String line = "";
int count = 0;
try {
BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
while ((line = br.readLine()) != null) {
if (line.contains("//")) {
count++;
} else if (line.contains("/*")) {
count++;
while (!line.contains("*/") && !(line = br.readLine()).contains("*/"));
}
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("count=" + count);
}
Of course the problem here is what if the "//", "/* " or "*/" sequences occur within quoted text....?
I haven't tested your code however, I believe this should work :
public static void main(String[] args) {
String line = "";
int count = 0;
try {
BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
while ((line = br.readLine()) != null) {
if (line.startsWith("//")) {
count++;
} else if (line.startsWith("/*")) {
count++;
while ((line = br.readLine())!=null && !line.endsWith("'*\'"));
}
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("count=" + count);
}
When you meet the /* you should increment the counter and skip the comment section.
Guys here is a easy solution. Just download the cloc software from this link for windows.
This software support every language & can accept folder of files also. Put your folder and cloc in same place and open cmd type this command
cloc-(version no).exe (folder name)
cloc-1.64.exe main
and have the no of lines, blank line and total no of lines in the code.
For more detail see this: http://cloc.sourceforge.net/
enter code here
public class FilterInputStreamDemo {
public static void main(String[] args) {
String line = "";
int comment_count = 0;
int line_count = 0;
int single_comment_count = 0;
int multiple_comment_count = 0;
try {
BufferedReader br = new BufferedReader(new FileReader("comments.txt"));
while ((line = br.readLine()) != null) {
line_count++;
if (line.startsWith("//")) {
comment_count++;
single_comment_count++;
} else if (line.startsWith("/*")) {
comment_count++;
multiple_comment_count++;
while (!(line = br.readLine()).endsWith("'*\'")) {
comment_count++;
multiple_comment_count++;
break;
}
}
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("comment_count=" + comment_count);
}
}
package com.usaa.training;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class CommentsReading {
public static void main(String[] args) {
String line = "";
int number_of_blocks = 0;
int comment_count = 0;
int line_count = 0;
int TODO = 0;
int single_comment_count = 0;
int multiple_comment_count = 0;
try {
File file = new File("C:\\code\\InvolvedPartyBasicInfoMapper.java");
BufferedReader br = new BufferedReader(new FileReader(file));
while ((line = br.readLine()) != null) {
line_count++;
;
if (line.contains("//")) {
if (line.contains("TODO")){
TODO++;
}
comment_count++;
single_comment_count++;
} else if (line.contains("/*") )
{
if (line.contains("TODO")){
TODO++;
}
comment_count++;
multiple_comment_count++;
if (line.endsWith("*/"))
{
break;
}
while (!(line = br.readLine()).endsWith("'*/'") )
{
line_count++;
comment_count++;
multiple_comment_count++;
if (line.endsWith("*/"))
{
number_of_blocks++;
break;
}
}
}
}
br.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Total # of Lines = " + line_count);
System.out.println("Total # of Comment Lines= " +comment_count);
System.out.println("Total # of Single line Comments= " +single_comment_count );
System.out.println("Total # of Comment lines with Block Comments = " +multiple_comment_count );
System.out.println("Total # of Block line Comments = " +number_of_blocks);
System.out.println("No of TODO's = " +TODO);
}
}

PrintWriter issue with even numbers

I'm having an issue here: I had this program printing all even numbers 0 through 1000 but after a friend made some changes it only prints "0" now. I've worked with it for a while and can't figure out if it's a loop issue or a printwriter issue. I took the loop out of the printWriter method and still nothing. What exactly am I doing wrong?
import java.io.FileNotFoundException;
import java.io.File;
import java.io.PrintWriter;
public class NumberWriter {
public static void main(String[] args) {
String fileName = "numbers.txt";
try {
PrintWriter outputStream = new PrintWriter(fileName);
for(int i = 0; i <= 1000; i++){
if (i%2==0){
outputStream.println(i + "");
outputStream.close();
}
}
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Don't close your PrintWriter (outputStream) or you won't get any more output. And your code can be optimized to increment by 2 and bypass the even test (this works because every even number is a multiple of two). And Java now has The try-with-resources Statement so you don't have to remember to close your PrintWriter,
try (PrintWriter outputStream = new PrintWriter(fileName)) {
for(int i = 0; i <= 1000; i += 2){
outputStream.println(Integer.toString(i));
}
} catch (FileNotFoundException e) {
e.printStackTrace():
}

Why won't the catch block run?

I have the following method to write an array to a text file. If a existing text file is given then it works fine but if a file that doesn't exist is given neither try-catch will run the code to restart the method. I'm not given any error or anything but the catch block won't run. I didn't think i would need to catch for an IOException but the code won't even run if i don't do that. So yea, anyone know how i can get this to work?
Edit: Forgot to mention the getInput method prompts the user for input.
private static void openFileWriter(String prompt, boolean append, int wordsperline, String[] story) {
try {
try {
save = new PrintWriter(new FileWriter(getInput(prompt), append));
wordsperline = 0;
save.println("");
save.println("");
save.println("Story start");
for (int x = 0; x <= story.length-1; x++) {
if (story[x] == null) {
} else {
if (wordsperline == 21) {
save.println(story[x]);
wordsperline = 0;
} else {
save.print(story[x]);
wordsperline++;
}
}
}
save.close();
} catch (FileNotFoundException e1) {
openFileWriter("File not found", append,wordsperline,story);
}
} catch (IOException e) {
// TODO Auto-generated catch block
openFileWriter("File not found", append,wordsperline,story);
}
}
If the File does not exist you cannot write to it, in your catch block you are trying to write the error to the File that doesn't exist. Also, I think you only need 1 catch block here, and note that one of the if statement blocks is empty.
try this:
try
{
save = new PrintWriter(new FileWriter(getInput(prompt), append));
wordsperline = 0;
save.println("");
save.println("");
save.println("Story start");
for(int x = 0; x <= story.length-1; x++)
{
if (story[x] == null)
{
}
else
{
if (wordsperline == 21)
{
save.println(story[x]);
wordsperline = 0;
}
else
{
save.print(story[x]);
wordsperline++;
}
}
}
save.close();
}
catch (FileNotFoundException e1)
{
System.err.println(e1.getMessage());
}
catch (IOException e)
{
System.err.println(e.getMessage());
}
See FileWriter javadoc.
Quoting from the constructor doc:
Throws:
IOException - if the named file exists but is a directory rather than a regular file, does not exist but cannot be created, or cannot be opened for any other reason
If you pass it a filename that doesn't exist, but is a legal filename in a location where you have permission to write, it simply creates the file.
Your code in fact does reach the catch blocks if you pass it a directory (somewhat oddly, it catches a FileNotFoundException in this situation for me rather than the documented IOException).
To check if a file exists, see File javadoc
Try this version and send the stack trace when you get the exception:
public static List<String> splitByLength(String filename, int length) {
List<String> splitWords = new ArrayList<String>();
for (int i = 0; i < str.length(); i += length) {
splitWords
.add(str.substring(i, Math.min(str.length(), i + length)));
}
return splitWords;
}
private static void openFileWriter(String prompt, boolean append,
int wordsperline, String[] story) {
PrintWriter save = null;
try {
save = new PrintWriter(new FileWriter("c:\\test.txt", append));
wordsperline = 0;
save.println("");
save.println("");
save.println("Story start");
for (int x = 0; x <= story.length - 1; x++) {
if (story[x] != null) {
List<String> splitWords = splitByLength(story[x], 21);
for (String line : splitWords) {
save.println(line);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (save != null) {
save.close();
}
}
}

DataOutputStream writing too much

What I currently have
I'm currently trying to create a little download manager in Java and I have a problem with writing the loaded bytes in a file. I'm using a DataOutputStream to write the byte-array which I read from a DataInputStream. Here is the class I created to do that:
public class DownloadThread extends Thread{
private String url_s;
private File datei;
public DownloadThread(String url_s, File datei){
this.url_s = url_s;
this.datei = datei;
}
public void run(){
// Connect:
int size = 0;
URLConnection con = null;
try {
URL url = new URL(url_s);
con = url.openConnection();
size = con.getContentLength();
// Set Min and Max of the JProgressBar
prog.setMinimum(0);
prog.setMaximum(size);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Download:
if (con != null || size != 0){
byte[] buffer = new byte[4096];
DataInputStream down_reader = null;
// Output:
DataOutputStream out = null;
try {
out = new DataOutputStream(new FileOutputStream(datei));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
// Load:
try {
down_reader = new DataInputStream(con.getInputStream());
int byte_counter = 0;
int tmp = 0;
int progress = 0;
// Read:
while (true){
tmp = down_reader.read(buffer);
// Check for EOF
if (tmp == -1){
break;
}
out.write(buffer);
out.flush();
// Set Progress:
byte_counter += tmp;
progress = (byte_counter * 100) / size;
prog.setValue( byte_counter );
prog.setString(progress+"% - "+byte_counter+"/"+size+" Bytes");
}
// Check Filesize:
prog.setString("Checking Integrity...");
if (size == out.size()){
prog.setString("Integrity Check passed!");
} else {
prog.setString("Integrity Check failed!");
System.out.println("Size: "+size+"\n"+
"Read: "+byte_counter+"\n"+
"Written: "+out.size() );
}
// ENDE
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
out.close();
down_reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// Clean Up...
load.setEnabled(true);
try {
this.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
This is currently an inner-class and the prog-Object is a JProgressBar from it's mother-class, so it can be accessed directly.
Example
I'm trying to download the Windows .exe Version of the TinyCC, which should be 281KB size. The file i downloaded with my download manager is 376KB big.
The Output from the Script looks like this:
Size: 287181
Read: 287181
Written: 385024
So it seems that the read bytes match the file-size but there are more bytes written. What am I missing here?
This is wrong:
out.write(buffer);
It should be
out.write(buffer, 0, tmp);
You need to specify how many bytes to write, a read doesn't always read a full buffer.
Memorize this. It is the canonical way to copy a stream in Java.
int count;
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}

Categories

Resources