• Post Reply Bookmark Topic Watch Topic
  • New Topic

trouble with a file  RSS feed

 
jake mullet
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a file that is downloaded from a server each day with records on each line. the file is called PUNCH.001. each file contains an X on the 6th element of the first line of the daily PUNCHfile and a Z on the 5th element of the last line of the same daily PUNCHfile. Problem is, sometimes the file gets cut off in the middle and then starts a new PUNCH.002--so..the first file is missing the "Z" line and the second is missing the "X" line. I have to check this file everyday, and if this wierd cutoff thing happens I have to manually cut and paste the two files together, arghh- How would I write a small program to check the PUNCH.001 file to see if there is the 'X' and 'Z' line and if it is missing one, grab the second (punch.002) and put them together. I am kinda new to this stuff so any help is greatly appreciated. thnkas alot.
here is what I have so far:
byte[] btBuffer =null;
boolean bReadFile = false;
String sINFileName = null;
int i;
InputStream fin;

if(sINFileName == null)
sINFileName = "c:\\dailyfile\\receive\\Punch.001";

sINFileName = "c:\\dailyfile\\receive\\Punch.001";
fin = new FileInputStream(sINFileName);
btBuffer = new byte[fin.available()];
int i = 0;
while(i < btBuffer.length) {
i = fin.read();
btBuffer[i] = (byte)i;
i++;
}
fin.close();

 
Bryan Fagan
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jake:
You create a buffer with a byte[]. Then, you read get the size of the buffer by calling fin.available();
btBuffer = new byte[fin.available()];
Problem:
fin.available means that the InputStream will retrieve as much of the Stream as it can without blocking. So, if it can't retrieve the whole stream, it will only retrieve what it can.
This is probably why you only get part of your file in punch.001.
Unless you can predict exactly how large your buffer should be at compile time, it would probably be better to use Collections like a java.util.ArrayList to hold your bytes.
With an ArrayList, you don't need to know how big the array will be as you can add as many bytes as you want.
You can't add a primitive like a byte to an ArrayList. ArrayLists take Object(s) as a parameter. So you must use a Byte wrapper (java.lang.Byte).
(Your code altered with an ArrayList and a Byte wrapper )
ArrayList btBuffer = new ArrayList();
boolean bReadFile = false;
String sINFileName = null;
InputStream fin;

if(sINFileName == null)
sINFileName = "c:\\dailyfile\\receive\\Punch.001";

sINFileName = "c:\\dailyfile\\receive\\Punch.001";
fin = new FileInputStream(sINFileName);
int i = 0;
while( ( i = fin.read() ) != -1 )
{
btBuffer.add( new Byte( (byte) i ) );
}
fin.close();
Output the file to the console
for( int j=0;j < btBuffer.size();j++ )<br /> {<br /> System.out.println("OUT: " + btBuffer.get( j ).toString() );<br /> }<br /> This way it doesn't matter how large or small the file, we always get the whole thing. Collections are really cool because you can store any Object, which means practically anything.<br /> Happy Programming -> :-)
Bryan

Originally posted by jake mullet:
I have a file that is downloaded from a server each day with records on each line. the file is called PUNCH.001. each file contains an X on the 6th element of the first line of the daily PUNCHfile and a Z on the 5th element of the last line of the same daily PUNCHfile. Problem is, sometimes the file gets cut off in the middle and then starts a new PUNCH.002--so..the first file is missing the "Z" line and the second is missing the "X" line. I have to check this file everyday, and if this wierd cutoff thing happens I have to manually cut and paste the two files together, arghh- How would I write a small program to check the PUNCH.001 file to see if there is the 'X' and 'Z' line and if it is missing one, grab the second (punch.002) and put them together. I am kinda new to this stuff so any help is greatly appreciated. thnkas alot.
here is what I have so far:
byte[] btBuffer =null;
boolean bReadFile = false;
String sINFileName = null;
int i;
InputStream fin;

if(sINFileName == null)
sINFileName = "c:\\dailyfile\\receive\\Punch.001";

sINFileName = "c:\\dailyfile\\receive\\Punch.001";
fin = new FileInputStream(sINFileName);
btBuffer = new byte[fin.available()];
int i = 0;
while(i < btBuffer.length) {
i = fin.read();
btBuffer[i] = (byte)i;
i++;
}
fin.close();

[This message has been edited by Bryan Fagan (edited May 10, 2001).]
[This message has been edited by Bryan Fagan (edited May 10, 2001).]
 
Ryan Langley
Ranch Hand
Posts: 46
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,
Hey there.. Here's some code that I wrote with your problem in mind. I don't think that it would be a good idea to read the both files completely into an array object so your program could maniputlate it. If the files are very large (I assume they are since they get cut in two parts sometimes) this could really pog down your system. You already have the files with the correct data, all you have to do is determine if the criteria exists for two files (X in 6th position of first line, Z in 5th position of last line). I decided that opening the two files and checking for the correct criteria first before any manipulation occurs is a good idea. No point in reading the whole thing in if it is correct. Using the RandomAccessFile class is perfect for this situation. It allows you to seek through the files and check for certain conditions. Once you determine that the files do in deed need to be concatinated, all you have to do is write all the characters in the file that has the X first to a new file, and then all the charactes from the second file. My code below is run by passing the two files as arguments (i.e. java KnockOut PUNCH.001 PUNCH.002). If the files need to be concatinated, it will place the result into the file knockout.txt. Hope this is helpful to you, and hopefully by reading it you can get a better grasp of how java works. Good luck!

RL
<pre>
/* Author: Ryan Langley
* Date: May 11, 2001
* Version: 0.1
*
* Usage: java KnockOut filename filename
*
* Function: Concatinates two files into a file called "knockout.txt" if
* one of the files has an 'X' character in the 6th position of the first
* line, and the other file has a 'Z' character in the 5th postion of the
* last line. If one of the files has both conditions, the concatination
* will not occur.
*/
import java.io.*;
public class KnockOut {
public static void main(String[] args) throws IOException {
// Make sure correct number of args were passed in command line.
if(args.length == 2) {
File punch1 = new File(args[0]);
File punch2 = new File(args[1]);

// Make sure args entered are valid files and can be read.
if(punch1.canRead() && punch2.canRead()) {
RandomAccessFile p1 = new RandomAccessFile(punch1, "r");
RandomAccessFile p2 = new RandomAccessFile(punch2, "r");
// Examine files for X and Z values in the correct position.
boolean xForp1 = checkForX(p1);
boolean zForp1 = checkForZ(p1);
boolean xForp2 = checkForX(p2);
boolean zForp2 = checkForZ(p2);
// Figure out if the files need to be concatinated.
if((xForp1 && zForp1) | | (xForp2 && zForp2)) {
System.out.println("One or more of the files entered is already a valid "
+ "file for this program.");
} else if((xForp1 && zForp2) | | (xForp2 && zForp1)) {
// Files meet layout criteria, so we can print data to a new file.
FileOutputStream ko = new FileOutputStream("knockout.txt");
PrintStream pko = new PrintStream(ko);
// Determine which file should be put in the new file first.
if(xForp1) {
printToFile(p1, pko);
printToFile(p2, pko);
} else {
printToFile(p2, pko);
printToFile(p1, pko);
}
// New file complete. Close all the open streams.
pko.close();
ko.close();
}
p2.close();
p1.close();
} else {
if(!punch1.canRead()) {
System.out.println("Error: " + punch1.toString() + " could not be read.");
}
if(!punch2.canRead()) {
System.out.println("Error: " + punch2.toString() + " could not be read.");
}
}
} else {
System.out.println("Error: Incorrect Usage.");
System.out.println("Correct usage: java KnockOut <file> file>");
}
System.exit(0);
}

public static boolean checkForX(RandomAccessFile raf) throws IOException {
raf.seek(5);
if((char)raf.read() == 'X') return true;
return false;
}

public static boolean checkForZ(RandomAccessFile raf) throws IOException {
long pos = raf.length() - 1;
raf.seek(pos);
while(pos != 0 && (char)raf.read() != '\n') {
raf.seek(--pos);
}
raf.seek(pos + 5);
if((char)raf.read() == 'Z') return true;
return false;
}
public static void printToFile(RandomAccessFile raf, PrintStream ps) throws IOException {
for(int i = 0; i < raf.length(); ++i) {
raf.seek(i);
ps.print((char)raf.read());
}
}
}
</pre>
[This message has been edited by Ryan Langley (edited May 16, 2001).]
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!