java RandomAccessFile parameter - java

I am trying to follow the below example found it here Java: Find if the last line of a file is empty to determine if a file finish by CRLF(empty line) however when I pass a String to the method RandomAccessFile says file Not Found. the problem is I cant feed it the file path, but I have the contents of the file as a String, so I tried to create a file using File f = new File(myString); and then pass the method the created file but it didnt work and it gave me the same error (File not Found) (it consideres the first line of the file as the path)!
how can I create a file accepted by RandomAccessFile, from my String that contains the contents of the file I want to check if it finishs by CRLF.
Hope I was clear.
public static boolean lastLineisCRLF(String filename) {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(filename, "r");
long pos = raf.length() - 2;
if (pos < 0) return false; // too short
raf.seek(pos);
return raf.read() == '\r' && raf.read() == '\n';
} catch (IOException e) {
return false;
} finally {
if (raf != null) try {
raf.close();
} catch (IOException ignored) {
}
}
}

If you have the file contents already in memory as a string, you don't need to write it to a file again to determine if the last line is empty. Just split the contents by an end-of-line character and then trim whitespace off the last line and see if anything is left:
String fileContent = "line1\nline2\nline3\nline4\n";
// -1 limit tells split to keep empty fields
String[] fileLines = fileContent.split("\n", -1);
String lastLine = fileLines[fileLines.length - 1];
boolean lastLineIsEmpty = false;
if(lastLine.trim().isEmpty())
{
lastLineIsEmpty = true;
}
//prints true, line4 followed by carriage return but
//no line 5
System.out.println("lastLineEmpty: " + lastLineIsEmpty);

Related

How to set next encoding to a file in Java

Here is my code which is reading file and replacing on a specific line the text but when is reading the(readAllLines method) lines and it have a symbol in the file which doesn't matches with the specified Charset it throws MalformedInputException.
For Example: I'm reading a text with UTF_8 charset but in file it has symbol "†" and it throws me MIE.
I would like to ask you how in the following code i can make a check when a MalformedInputException found and try the next encoding . For example when the encoding is UTF_8, to try the next one UTF_16 etc. and when it matches to read the file properly.
public boolean replaceTextInSpecificLine(String fileName, int lineNumber, String content, Charset cs)
{
try
{
scan = new Scanner(System.in);
File filePath = readFile(fileName, true);
List<String> lines = null;
if(filePath !=null)
{
lines = Files.readAllLines(filePath.toPath(), cs);
while (lineNumber < 0 || lineNumber > lines.size() - 1)
{
System.out.print("Wrong line number or the file is empty! Enter another line: ");
lineNumber = scan.nextInt();
scan.nextLine();
}
lines.set(lineNumber - 1, content);
Files.write(filePath.toPath(), lines, cs);
System.out.println("Successfully saved!");
return true;
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
close(scan);
}
return false;
}
I would avoid switching encodings while reading the file and simply reread the file with the next encoding. Something like this would be sufficient:
List<String> getAllLines(File file, Charset... charsets) {
for (Charset cs: charsets) {
try {
return Files.readAllLines(file.toPath(), cs);
} catch (MalformedInputException e) {
...
} catch (IOException e) {
...
}
}
// error
}
(this is just an example, your arguments may vary based on need)
If you switched encodings while reading the document, you have the potential of interpreting some characters as valid UTF-8 characters when in fact they were ISO-8859-1 characters.

program only read last line in .txt file java

I have a problem and don't know what to do. This method is supposed to read all the text in a .txt document. My problem is when the document contains more then one line of text and the program only read the last line. The program don't need to worry about signs like . , : or spaces, but it have to read all the letters. Can anybody help me?
example text
hello my name is
(returns the right result)
hello my
name is
(returns only name is)
private Scanner x;
String readFile(String fileName)
{
try {
x = new Scanner (new File(fileName + (".txt")));
}
catch (Exception e) {
System.out.println("cant open file");
}
while (x.hasNext()) {
read = x.next();
}
return read;
}
It's because when you use read = x.next(), the string in the read object is always being replaced by the text in the next line of the file. Use read += x.next() or read = read.concat(x.next()); instead.
You replace every read with every read(). Also, you didn't close() your Scanner. I would use a try-with-resources and something like,
String readFile(String fileName)
{
String read = "";
try (Scanner x = new Scanner (new File(fileName + (".txt")));) {
while (x.hasNextLine()) {
read += x.nextLine() + System.lineSeparator(); // <-- +=
}
} catch (Exception e) {
System.out.println("cant open file");
}
return read;
}

Converting a set of characters into a different string array using java

I am trying to read a data from a file. I have following code.
public void ReadFile()
{
File sdcard = android.os.Environment.getExternalStorageDirectory();
File directory = new File(sdcard.getAbsolutePath()+ "/MyDirectory");
File file = new File(directory,"textfile1.txt");
try (FileInputStream fis = new FileInputStream(file)) {
char stringComma = new Character(',');
System.out.println("Total file size to read (in bytes) : "+ fis.available());
int content;
while ((content = fis.read()) != -1) {
// convert to char and display it
Log.d(TAG, "reading a file");
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
I have file format as follows [textfile1.txt]
[12],84359768069 //some numbers
[34],56845745740
[44],36344679992
[99],46378467467
When i am reading this file each character will read at a time. I want to split this and store in different string arrays like
str1 = [12]
str2 = 84359768069
How i can achieve this?
You're currently reading a byte at a time, because you're using InputStream. That's the first thing to fix - you should be using a Reader for text data. The best approach is to wrap your InputStream in an InputStreamReader.
Next, it sounds like you want to read a line at a time rather than just a character at a time. The easiest way of doing that is to use a BufferedReader wrapping an InputStreamReader.
(If you were using Java 7+, all of this could be achieved very nicely using Files.newBufferedReader - you just need to supply the Path and the Charset. Until Android supports that, you'll need to just do the wrapping manually. It's not too painful though.)
One you're reading a line at a time, you then need to split the line by comma - look at using String.split for this. I would then suggest you create a class to store these two separate values. So each line will be transformed into an instance of your class.
Finally, create a List<YourCustomClass> and add to it as you read the file.
That's given an overview of how to achieve each step - hopefully enough detail to enable you to get going, but not spoon-feeding you enough to hamper you actually learning from the experience.
A simple solution would be to parse the readed characters:
public void ReadFile()
{
File sdcard = android.os.Environment.getExternalStorageDirectory();
File directory = new File(sdcard.getAbsolutePath()+ "/MyDirectory");
File file = new File(directory,"textfile1.txt");
try (FileInputStream fis = new FileInputStream(file)) {
char stringComma = new Character(',');
System.out.println("Total file size to read (in bytes) : "+ fis.available());
int content;
String str1="";
String str2 = "";
boolean commaFound=false;
while ((content = fis.read()) != -1) {
// convert to char and display it
Log.d(TAG, "reading a file");
if ((char)content==',')
{
commaFound = true;
}
else if ((char)content=="\n")
{
System.out.printlnt("str1="+str1+"\nstr2="+str2);
commaFound = false;
str1 = "";
str2 = "";
}
else
{
if (commaFound)
{
str2 += (char)content;
}
else
{
str1 += (char)content;
}
}
System.out.print((char) content);
}
} catch (IOException e) {
e.printStackTrace();
}
}

Get the offset of previous line in a file

I'm extracting data from a file line by line into a database and i can't figure out a proper way to flag lines that I've already read into my database.
I have the following code that I use to iterate through the file lines and I attempt to verify
that the line has my flag or else I try to append the flag to the file line
List<String> fileLines = new ArrayList<String>();
File logFile = new File("C:\\MyStuff\\SyslogCatchAllCopy.txt");
try {
RandomAccessFile raf = new RandomAccessFile(logFile, "rw");
String line = "";
String doneReadingFlag = "##";
Scanner fileScanner = new Scanner(logFile);
while ((line = raf.readLine()) != null && !line.contains(doneReading)) {
Scanner s = new Scanner(line);
String temp = "";
if (!s.hasNext(doneReadingFlag)) {
fileLines.add(line);
raf.write(doneReadingFlag.getBytes(), (int) raf.getFilePointer(),
doneReadingFlag.getBytes().length);
} else {
System.err.println("Allready Red");
}
}
} catch (FileNotFoundException e) {
System.out.println("File not found" + e);
} catch (IOException e) {
System.out.println("Exception while reading the file ");
}
// return fileLines;
// MoreProccessing(fileLines);
This code appends the flag to the next line and it overwrites the characters in that position
Any Help ?
When you write to a file, it doesn't insert do you should expect it to replace the characters.
You need to reserve space in the file for information you want to change or you can add information to another file.
Or instead of marking each file, you can store somewhere the lines number (or better the character position) you have read up to.
If you are not restarting your process you can have process read the file as it is appended (meaning you might not need to store where you are up to anywhere)
#Peter Lawrey I did as you said and it worked for me like that:
as follows:
ArrayList<String> fileLines=new ArrayList<String>();
File logFile=new File("C:\\MyStuff\\MyFile.txt");
RandomAccessFile raf = new RandomAccessFile(logFile, "rw");
String line="";
String doneReadingFlag="#";
long oldOffset=raf.getFilePointer();
long newOffset=oldOffset;
while ((line=raf.readLine())!=null)
{
newOffset=raf.getFilePointer();
if(!line.contains(doneReadingFlag))
{
fileLines.add(line);
raf.seek((long)oldOffset);
raf.writeChars(doneReadingFlag);
raf.seek(newOffset);
System.out.println("Line added and flaged");
}
else
{
System.err.println("Already Red");
}
oldOffset=newOffset;
}

Deleting the last line of a file with Java

I have a .txt file, which I want to process in Java. I want to delete its last line.
I need ideas on how to achieve this without having to copy the entire content into another file and ignoring the last line. Any suggestions?
You could find the beginning of the last line by scanning the file and then truncate it using FileChannel.truncate or RandomAccessFile.setLength.
By taking RandomAccessFile you can:
use method seek(long) to jump forward and read those lines. But you won't know exactly how big the jump should be.
to delete last lines you need the position of begin of last line so before reading each line store their file pointer position (method getFilePointer()). Deleting to that position you use setLength(long).
Code would be something like this:
LinkedList<String> lines=null;
int howMuch = 1; // one line to read and delete
try{
RandomAccessFile raf = new RandomAccessFile(inputFileName, "rw");
System.out.println("File Length="+raf.length());
long step = 20; // here I advice to write average length of line
long jump = raf.length()<step*howMuch?
0:
raf.length()-step*howMuch;
raf.seek(jump);
lines = new LinkedList<String>();
LinkedList<Long> pos = new LinkedList<Long>();
Entry<LinkedList<String>,LinkedList<Long>> rLinesRead = getRemainingLines(raf,
new AbstractMap.SimpleEntry<LinkedList<String>,LinkedList<Long>> (lines,pos));
while(rLinesRead.getKey().size()<howMuch){
if(jump<step)
if(jump<=0)
break;
else{
jump=0;
raf.seek(jump);
rLinesRead=getRemainingLines(raf,rLinesRead);
break;
}
else
jump=jump-step;
raf.seek(jump);
rLinesRead=getRemainingLines(raf,rLinesRead);
}
int originalSize=rLinesRead.getKey().size();
lines=rLinesRead.getKey();
pos=rLinesRead.getValue();
for (int i=0;i<originalSize-howMuch;++i){
lines.removeFirst();
pos.removeFirst();
}
if(!pos.isEmpty())
raf.setLength(pos.getFirst()); // before last(from EOF) returned fully read lines in file
}catch(Exception ex){
ex.printStackTrace();
} finally{
try { raf.close(); } catch (Exception e) { e.printStackTrace(); }
}
//returns line to EOF with their begin file pointer positions
private Entry<LinkedList<String>,LinkedList<Long>> getRemainingLines(RandomAccessFile raf,
Entry<LinkedList<String>,LinkedList<Long>> linesAlreadyLoadedFromEnd) throws IOException{
LinkedList<String> pLines = linesAlreadyLoadedFromEnd.getKey();
LinkedList<Long> pPos = linesAlreadyLoadedFromEnd.getValue();
long init=raf.getFilePointer();
String str = raf.readLine();
if(pPos.size()>0?pPos.getFirst()==0:false || str==null)
return linesAlreadyLoadedFromEnd;
LinkedList<String> lines = new LinkedList<String>();
LinkedList<Long> pos = new LinkedList<Long>();
if(init==0L ){
lines.add(str);
pos.add(0L);
}
Long tmpPos = raf.getFilePointer();
while ((str = raf.readLine())!=null && !pPos.contains(tmpPos)){
lines.add(str);
pos.add(tmpPos);
tmpPos = raf.getFilePointer();
}
pLines.addAll(0,lines);
pPos.addAll(0,pos);
return new AbstractMap.SimpleEntry<LinkedList<String>,LinkedList<Long>> (pLines,pPos);
}

Categories