Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
My teacher gave us homework to reverse a integer file.
lets say I have a file that contains 1,2,3,4,5.
My homework is to reverse it and write it into a file so it contains 5,4,3,2,1.
I already did that with List. and it worked.
But my teacher told me not to do it with List.
Can someone help me please ?
static void getNumFiles(File file){
InputStream inputStream = null;
OutputStream outputStream = null;
List<Integer> list = new ArrayList<>();
int actuallyRead = 0;
byte[] buffer = new byte[4];
int[] arr = new int[list.size()];
int counter = list.size();
int x = 0;
try {
inputStream = new FileInputStream(file);
outputStream = new FileOutputStream(file);
while((actuallyRead = inputStream.read(buffer)) != -1){
x = ByteBuffer.wrap(buffer).getInt();
list.add(x);
}
for (int i = 0; i < arr.length; i++) {
arr[i] = list.get(list.size() - i) ;
}
exampleWriteIntegerArray(arr, file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
This answer assumes the file in question is a simple text file. The file type was not clear in the original question.
Just a quick snippet of code that achieves your assignment without using a list.
It reads the input file and uses a StringBuilder to reverse the input. The reversed input can then be written to a desired output location.
public static void main(final String[] args) {
try {
String fileContent = new String(Files.readAllBytes(Paths.get("D:/12345.txt"))); // Read file
StringBuilder sb = new StringBuilder(fileContent);
String reversedContent = sb.reverse().toString();
PrintWriter writer = new PrintWriter(new File("D:/54321.txt")); // Create new file and output the reversed String.
writer.println(reversedContent);
writer.close();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
Input: 1,2,3,4,5
Output: 5,4,3,2,1
It's not entirely clear from your question what exactly your teacher expects from you. Also, it looks like the file is a binary file with integers rather than a text file with integer values.
If that is true, without writing the program for you:
Open your file as a RandomAccessFile.
Use its length() function to determine how many integers are contained in it (Note that the length is in bytes, while integers are 32 bit).
Move to the last int position in the file using the seek() method, read it using readInt(), output it.
Move one position before that, do the same, until you're at position 0 - at which point you've read the whole file.
If you use String's reverse function then you cannot handle the following situation 250,150,623changes to 326,051,052.
And also I cannot clearly understand the your files context. Does it contains the , character for delimiter character? If not, what is your file's delimiter?
At the beginning of my answer I said that you cannot handle that. However, if you know what is your files delimiter then you can use #ProfessionalCode's code with that extras,
public static void main(final String[] args) {
try {
String fileContent = new String(Files.readAllBytes(Paths.get("D:/12345.txt"))); // Read file
StringBuilder sb = new StringBuilder(fileContent);
String reversedContent = sb.reverse().toString();
char delimiter = " "; //let say it is whitespace
String temp = ""; //it will use between two delimiters to get reverse String
PrintWriter writer = new PrintWriter(new File("D:/54321.txt")); // Create new file and output the reversed String
for (int i = 0; i < reversedContent.length(); i++){
if(reverseContent.charAt(i) == delimiter){
writer.print(temp.reverse().toString());
writer.print(delimiter.reverse().toString()); //writing your delimiter between all numbers, if it is like ",-" it needed to be reversed to "-,"
temp = "";
}else{
temp += reverseContent.charAt(i);
}
}
writer.print(temp.reverse().toString()); //for last number
writer.close();
}catch (IOException ex) {
ex.printStackTrace();
}
}
Related
I read about someone having troubles with BufferedReader: the reader simply do not read the first lines. I have instead the opposite problem. For example, in a text file with 300 lines, it arrives at 200, read it half of it and then the following string is given null, so it stops.
private void readerMethod(File fileList) throws IOException {
BigInteger steps = BigInteger.ZERO;
BufferedReader br = new BufferedReader(new FileReader(fileList));
String st;
//reading file line by line
try{
while (true){
st = br.readLine();
if(st == null){
System.out.println("Null string at line " + steps);
break;
}
System.out.println(steps + " - " + st);
steps = steps.add(BigInteger.ONE);
}
}catch(Exception e){
e.printStackTrace();
}
finally{
try{
br.close();
}catch(Exception e){}
}
}
The output of the previous slice of code is as expected until it reaches line 199 (starting from 0). Consider a file with 300 lines.
...
198 - 3B02D5D572B66A82F9D21EE809320DB3E250C6C9
199 - 6E2C69795CB712C27C4097119CE2C5765
Null string at line 200
Notice that, all lines have the same length, so in this output line 199 is not even complete. I checked the file text, and it's correct: it contains all 300 lines and they are all of the same length. Also, in the text there are only capitals letters and numbers, as you can see.
My question is: how can i fix this? I need that the BufferedReader read all the text, not just a part of it.
As someone asked i add here the remaining part of the code. Please notice that all capital names are constant of various type (int, string etc).
This is the method that is called by the main thread:
public void init(){
BufferedWriter bw = null;
List<String> allLines = createRandomStringLines(LINES);
try{
String fileName = "SHA1_encode_text.txt";
File logFile = new File(fileName);
System.out.println(logFile.getCanonicalPath());
bw = new BufferedWriter(new FileWriter(logFile));
for(int i = 0; i < allLines.size(); i++){
//write file
String o = sha1FromString(allLines.get(i));
//sha1FromString is a method that change the aspect of the string,
//replacing char by char. Is not important at the moment.
bw.write(o + "\n");
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
bw.close();
}catch(Exception e){}
}
}
The method that create the list of random string is the following. "SYMBOLS" is just a String contains all avaiable chars.
private List<String> createRandomStringLines(int i) {
List<String> list = new ArrayList<String>();
while(i!=0){
StringBuilder builder = new StringBuilder();
int count = 64;
while (count-- != 0) {
int character = (int)(Math.random()*SYMBOLS.length());
builder.append(SYMBOLS.charAt(character));
}
String generatedString = builder.toString();
list.add(generatedString);
i--;
}
return list;
}
Note that, the file written is totally correct.
Okay, thanks to the user ygor, i manage to resolve it. The problem was that the BufferReader stars his job when the BufferWriter isn't closed yet. It was sufficient to move the command line that require the reader to work, after the bufferWriter.close() command.
I wrote a program that generates random numbers into two text files and random letters into a third according the two constant files. Now I need to read from each text file, line by line, and put them together. The program is that the suggestion found here doesn't really help my situation. When I try that approach it just reads all lines until it's done without allowing me the option to pause it, go to a different file, etc.
Ideally I would like to find some way to read just the next line, and then later go to the line after that. Like maybe some kind of variable to hold my place in reading or something.
public static void mergeProductCodesToFile(String prefixFile,
String inlineFile,
String suffixFile,
String productFile) throws IOException
{
try (BufferedReader br = new BufferedReader(new FileReader(prefixFile)))
{
String line;
while ((line = br.readLine()) != null)
{
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(productFile, true))))
{
out.print(line); //This will print the next digit to the right
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
}
}
}
}
EDIT: The digits being created according to the following. Basically, constants tell it how many digits to create in each line and how many lines to create. Now I need to combine these together without deleting anything from either text file.
public static void writeRandomCodesToFile(String codeFile,
char fromChar, char toChar,
int numberOfCharactersPerCode,
int numberOfCodesToGenerate) throws IOException
{
for (int i = 1; i <= PRODUCT_COUNT; i++)
{
int I = 0;
if (codeFile == "inline.txt")
{
for (I = 1; I <= CHARACTERS_PER_CODE; I++)
{
int digit = (int)(Math.random() * 10);
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
{
out.print(digit); //This will print the next digit to the right
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
System.exit(1);
}
}
}
if ((codeFile == "prefix.txt") || (codeFile == "suffix.txt"))
{
for (I = 1; I <= CHARACTERS_PER_CODE; I++)
{
Random r = new Random();
char digit = (char)(r.nextInt(26) + 'a');
digit = Character.toUpperCase(digit);
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
{
out.print(digit);
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
System.exit(1);
}
}
}
//This will take the text file to the next line
if (I >= CHARACTERS_PER_CODE)
{
{
Random r = new Random();
char digit = (char)(r.nextInt(26) + 'a');
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(codeFile, true))))
{
out.println(""); //This will return a new line for the next loop
}
catch (FileNotFoundException e)
{
System.err.println("File error: " + e.getMessage());
System.exit(1);
}
}
}
}
System.out.println(codeFile + " was successfully created.");
}// end writeRandomCodesToFile()
Being respectfull with your code, it will be something like this:
public static void mergeProductCodesToFile(String prefixFile, String inlineFile, String suffixFile, String productFile) throws IOException {
try (BufferedReader prefixReader = new BufferedReader(new FileReader(prefixFile));
BufferedReader inlineReader = new BufferedReader(new FileReader(inlineFile));
BufferedReader suffixReader = new BufferedReader(new FileReader(suffixFile))) {
StringBuilder line = new StringBuilder();
String prefix, inline, suffix;
while ((prefix = prefixReader.readLine()) != null) {
//assuming that nothing fails and the files are equals in # of lines.
inline = inlineReader.readLine();
suffix = suffixReader.readLine();
line.append(prefix).append(inline).append(suffix).append("\r\n");
// write it
...
}
} finally {/*close writers*/}
}
Some exceptions may be thrown.
I hope you don't implement it in one single method.
You can make use of iterators too, or a very simple reader class (method).
I wouldn't use List to load the data at least I guarantee that the files will be low sized and that I can spare the memory usage.
My approach as we discussed by storing the data and interleaving it. Like Sergio said in his answer, make sure memory isn't a problem in terms of the size of the file and how much memory the data structures will use.
//the main method we're working on
public static void mergeProductCodesToFile(String prefixFile,
String inlineFile,
String suffixFile,
String productFile) throws IOException
{
try {
List<String> prefix = read(prefixFile);
List<String> inline = read(inlineFile);
List<String> suffix = read(productFile);
String fileText = interleave(prefix, inline, suffix);
//write the single string to file however you want
} catch (...) {...}//do your error handling...
}
//helper methods and some static variables
private static Scanner reader;//I just prefer scanner. Use whatever you want.
private static StringBuilder sb;
private static List<String> read(String filename) throws IOException
{
List<String> list = new ArrayList<String>;
try (reader = new Scanner(new File(filename)))
{
while(reader.hasNext())
{ list.add(reader.nextLine()); }
} catch (...) {...}//catch errors...
}
//I'm going to build the whole file in one string, but you could also have this method return one line at a time (something like an iterator) and output it to the file to avoid creating the massive string
private static String interleave(List<String> one, List<String> two, List<String> three)
{
sb = new StringBuilder();
for (int i = 0; i < one.size(); i++)//notice no checking on size equality of words or the lists. you might want this
{
sb.append(one.get(i)).append(two.get(i)).append(three.get(i)).append("\n");
}
return sb.toString()
}
Obviously there is still some to be desired in terms of memory and performance; additionally there are ways to make this slightly more extensible to other situations, but it's a good starting point. With c#, I could more easily make use of the iterator to make interleave give you one line at a time, potentially saving memory. Just a different idea!
I am new to Java. I am trying to added few words from a text file to my existing text based word list. I have the below code doing
Add words from an file to existing list
Sort the list of words
Save the words to a text file
"wordList" is an arraylist with existing words.
private void updateDictionaryFile(String filepath) {
String textCurrentLine = "";
BufferedReader dictionaryFile = null;
try {
Scanner fileScanner = new Scanner(new File(filepath));
while(fileScanner.hasNextLine()){
System.out.println("fileScanner.hasNextLine() "+ fileScanner.hasNextLine());
textCurrentLine = fileScanner.nextLine();
if(textCurrentLine.length() > 0)
if (!wordList.contains(textCurrentLine)) {
wordList.add(textCurrentLine);
}
}
Collections.sort(wordList);
String newFile = filepath.replace(".txt", "_new.txt");
PrintWriter pw = new PrintWriter(new FileOutputStream(newFile));
for (int i = 0; i < wordList.size(); i++) {
pw.println(wordList.get(i).toString());
}
pw.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (dictionaryFile != null) {
dictionaryFile.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Word listed in new file is not sorted. Am I missing something in between?
Below is the output
A
Achieve
Although
Anything
Ask
Avoid
Badly
Bluma
But
Find
Forget
Goal
Goals
How
In
It
Just
Keep
Know
NOT
Often
Once
One
Psychologists
Reasoning
Reject
Remember
Research
Russian
Shifting
Sidestep
So
Sometimes
Start
Stop
The
This
Those
Under
Visualise
Visualising
We
What
When
With
You
Zeigarnik
a
aa
aah
aahed
aahing
aahs
aal
aalii
aaliis
aals
aardvark
aardwolf
aargh
aarrgh
aarrghh
aas
Collections.sort(wordList); will work perfectly. if need to ignore the case then use below code.
Collections.sort(wordList,String.CASE_INSENSITIVE_ORDER);
I'm reading from a file that has the following format:
name : symptoms : causes : treatments : rate : prognosis
There are a total of 21 entries but when I try to read from the file and use .split(":");, the output changes each time but is always along the lines of: [Ljava.lang.String;#614951ff. I'm guessing it's the pointer or memory address but I want the String value. I'm not getting any exceptions though so I'm not sure where I've gone wrong. The purpose of the method is to read the file and split into an array using the delimiter for the given file row selected.
public String[] readCancer(int row) {
cancers = new String[22];
FileInputStream fis;
InputStreamReader isr;
BufferedReader br = null;
String eachCancer;
String[] splitCancer = null;
int j = 0;
try {
fis = new FileInputStream(myData);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
input = new Scanner(br);
while(input.hasNext() && j < 23) {
cancers[j++] = input.nextLine();
}
eachCancer = cancers[row].toString();
splitCancer = eachCancer.split(":");
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with file input");
} finally {
try {
if(br != null) {
br.close();
}
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem closing the file");
}
}
return splitCancer;
}
To print the contents of array :
1) System.out.println(Arrays.deepToString(splitCancer));
2) System.out.println(Arrays.toString(splitCancer));
3) System.out.println(Arrays.asList(splitCancer));
If you want to display the string array, you should use:
System.out.println(Arrays.toString(splitCancer));
Because when you print splitCancer you'll get the address of the array and not the content of it.
Of course you can print the content in other ways:
for(String str : splitCancer) {
System.out.println(str);
}
Currently I have the following:
public String[] readCancer() {
cancers = new String[22];
split = new String[22];
FileInputStream fis;
InputStreamReader isr;
BufferedReader br = null;
String eachCancer;
int j = 0;
try {
fis = new FileInputStream(myData);
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
input = new Scanner(br);
while(input.hasNext() && j < 23) {
cancers[j] = input.nextLine().toString();
//cancers[j] = input.nextLine();
split[j] = cancers[j].split(":");
//split[j] = "blah"; this line works
j++;
}
System.out.println(Arrays.toString(split));
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with file input");
} finally {
try {
if(br != null) {
br.close();
}
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem closing the file");
}
}
return split;
//return split[j]; does not work
}
In my while loop, I keep getting compile errors saying it requires a String but found Stirng[] for split. When I try something simpler, such as split[j] = "blah";, there are no compile errors. I can return cancers perfectly but I need to split by the : delimiter and that seems to be something I cant get my head around. When I try return split[j], then I get another compile error saying it requires a String[] but found String. I've been at this for more than an hour, read through examples in my textbook and tutorials online for using split but it still isn't working. This is the only part of my program that I'm not sure how to do.
I tried pasting the entire file but it came a horrid block of text, so here are 2 lines from it. Each line has the same format but differing lengths:
The general format of the file is name : symptoms : causes : treatment : rate : prognosis
The rate is a String since it is unknown for some diseases and when it is known, the rate is not always out of 250,000. Sometimes it is out of 1,000,000 or 100,000, etc... .
acute promyelocytic leukemia : easy bruising, rapid internal bleeding, fatigue, anemia, frequent fever, infection, blood clots : PML and RARA genes : Medications, chemotherapy : 1 in 250,000 : Good
familial cylindromatosis : numerous skin tumours, ulcers, infection, impaired eyesight, hearing, smell, balance : CYLD gene : Surgery, chemotherapy : Unknown : Unknown
My most recent code attempt is at Unusual output from using split()
The 2 arrays of cancers and split are private String[] as field variables declared outside any of the methods. The variable myData is a private File also declared as a field variable outside any of the methods. I have checked and already verified the file path is correct.
The main method that calls the method:
public static void main(String[] args) {
CancerGUI _gui = new CancerGUI();
String[] resultCancer;
resultCancer = _gui.readCancer();
//System.out.println(resultCancer);
System.out.println(Arrays.toString(resultCancer));
}
I am only calling it in the main method to test whether it correctly returns the String[]. Once it does, then I will call it in a different method that adds the data to a GUI (this part I am reasonably confident I know how to do and have examples from my instructor and textbook to follow).
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I guess this comes down to reading and writing to the same file. I would like to be able to return the same text file as is input, but with all integer values quadrupled. Should I even be attempting this with Java, or is it better to write to a new file and overwrite the original .txt file?
In essence, I'm trying to transform This:
12
fish
55 10 yellow 3
into this:
48
fish
220 40 yellow 12
Here's what I've got so far. Currently, it doesn't modify the .txt file.
import java.io.*;
import java.util.Scanner;
public class CharacterStretcher
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner( System.in );
System.out.println("Copy and paste the path of the file to fix");
// get which file you want to read and write
File file = new File(keyboard.next());
File file2 = new File("temp.txt");
BufferedReader reader;
BufferedWriter writer;
try {
// new a writer and point the writer to the file
FileInputStream fstream = new FileInputStream(file);
// Use DataInputStream to read binary NOT text.
reader = new BufferedReader(new InputStreamReader(fstream));
writer = new BufferedWriter(new FileWriter(file2, true));
String line = "";
String temp = "";
int var = 0;
int start = 0;
System.out.println("000");
while ((line = reader.readLine()) != null)
{
System.out.println("a");
if(line.contains("="))
{
System.out.println("b");
var = 0;
temp = line.substring(line.indexOf('='));
for(int x = 0; x < temp.length(); x++)
{
System.out.println(temp.charAt(x));
if(temp.charAt(x)>47 && temp.charAt(x)<58) //if 0<=char<=9
{
if(start==0)
start = x;
var*=10;
var+=temp.indexOf(x)-48; //converts back into single digit
}
else
{
if(start!=0)
{
temp = temp.substring(0, start) + var*4 + temp.substring(x);
//writer.write(line.substring(0, line.indexOf('=')) + temp);
//TODO: Currently writes a bunch of garbage to the end of the file, how to write in the middle?
//move x if var*4 has an extra digit
if((var<10 && var>2)
|| (var<100 && var>24)
|| (var<1000 && var>249)
|| (var<10000 && var>2499))
x++;
}
//start = 0;
}
System.out.println(temp + " " + start);
}
if(start==0)
writer.write(line);
else
writer.write(temp);
}
}
System.out.println("end");
// writer the content to the file
//writer.write("I write something to a file.");
// always remember to close the writer
writer.close();
//writer = null;
file2.renameTo(file); //TODO: Not sure if this works...
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Given that this is a pretty quick and simple hack of a formatted text file, I don't think you need to be too clever about it.
Your logic for deciding whether you are looking at a number is pretty complex and I'd say it's overkill.
I've written up a basic outline of what I'd do in this instance.
It's not very clever or impressive, but should get the job done I think.
I've left out the overwriting and reading the input form the console so you get to do some of the implementation yourself ;-)
import java.io.*;
public class CharacterStretcher {
public static void main(String[] args) {
//Assumes the input is at c:\data.txt
File inputFile = new File("c:\\data.txt");
//Assumes the output is at c:\temp.txt
File outputFile = new File("c:\\temp.txt");
try {
//Construct a file reader and writer
final FileInputStream fstream = new FileInputStream(inputFile);
final BufferedReader reader = new BufferedReader(new InputStreamReader(fstream));
final BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile, false));
//Read the file line by line...
String line;
while ((line = reader.readLine()) != null) {
//Create a StringBuilder to build our modified lines that will
//go into the output file
StringBuilder newLine = new StringBuilder();
//Split each line from the input file by spaces
String[] parts = line.split(" ");
//For each part of the input line, check if it's a number
for (String part : parts) {
try {
//If we can parse the part as an integer, we assume
//it's a number because it almost certainly is!
int number = Integer.parseInt(part);
//We add this to out new line, but multiply it by 4
newLine.append(String.valueOf(number * 4));
} catch (NumberFormatException nfEx) {
//If we couldn't parse it as an integer, we just add it
//to the new line - it's going to be a String.
newLine.append(part);
}
//Add a space between each part on the new line
newLine.append(" ");
}
//Write the new line to the output file remembering to chop the
//trailing space off the end, and remembering to add the line
//breaks
writer.append(newLine.toString().substring(0, newLine.toString().length() - 1) + "\r\n");
writer.flush();
}
//Close the file handles.
reader.close();
writer.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You may want to consider one of these:
Build the new file in memory, rather than trying to write to the same file you are reading from. You could use StringBuilder for this.
Write to a new file, then overwrite the old file with the new one. This SO Question may help you there.
With both of these, you will be able to see your whole output, separate from the input file.
Additionally, with option (2), you don't have the risk of the operation failing in the middle and giving you a messed up file.
Now, you certainly can modify the file in-place. But it seems like unnecessary complexity for your case, unless you have really huge input files.
At the very least, if you try it this way first, you can narrow down on why the more complicated version is failing.
You cannot read and simultaneously write to the same file, because this would modify the text you currently read. This means, you must first write a modified new file and later rename it to the original one. You probably need to remove the original file before renameing.
For renaming, you can use File.renameTo or see one of the many SO's questions
You seem to parse integers in your code by collecting single digits and adding them up. You should consider using either a Scanner.nextInt or employ Integer.parseInt.
You can read your file line by line, split the words at white space and then parse them and check if it is either an integer or some other word.