Renaming a RandomAccessFile - java

i have a RAF called data.bin and a temporary RAF called temp.bin.
data = new RandomAccessFile("data.bin","rws");
temp = new RandomAccessFile("temp.bin","rws");
the temp file is basically the data.bin file but i alter the information in it. so once im done altering the temp file how do i change the name of temp.bin to data.bin and delete the old data.bin?
ive seen some things about renaming Files with .renameTo() and stuff but that does apply to a RandomAccessFile. and i couldnt find any method like that for RAFs

RandomAccessFile was not designed to replace the File class.
It was designed to allow reading an writing only well more or less.
Please use the File class to do the renaming.

Close RAF and use java.nio.file.Files.move to rename the temp file. File.renameTo has a draw back. If it fails to rename the file you will never know why since it just returns true or false. Files.move throws IOException if fails.

I had same problem.
I did something like this:
data.close();
temp.close();
File tempfile = new File("c:/.../temp.bin");
File datafile = new File("c:/.../data.bin");
tempfile.renameTo(datafile);
For more information: http://www.tutorialspoint.com/java/io/file_renameto.htm

RandomAccessFile purpose is to read/write information. To handle file names, existence, etc., you must use the File class.
In your case, you should do something like this:
File d = new File("data"); // Declare your data RAF through File
RandomAccessFile data = new RandomAccessFile(d,"rws");
public void foo(){
File t = new File("temp"); // Declare your temp RAF through File
RandomAccessFile temp = new RandomAccessFile(t,"rws");
//TODO data RAF alteration
data.close();
d.delete(); //First delete data File, just in case
temp.close();
File f = new File("data");
t.renameTo(f);
}

Related

Get specific file inputstream from TarArchiveInputStream

I have a tar file and which contains many files. I need to get a specific file from tar file and read data from that file.
I am untaring file using the below code and I will read this returned input stream using some other function.
private InputStream unTar(final File inputFile, final File outputDir) throws FileNotFoundException, IOException, ArchiveException {
InputStream versionInputStream = null;
final InputStream is = new FileInputStream(inputFile);
final TarArchiveInputStream debInputStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", is);
TarArchiveEntry entry = null;
while ((entry = (TarArchiveEntry)debInputStream.getNextEntry()) != null) {
if (!entry.isDirectory() && entry.getName().equals("version.txt")) {
versionInputStream = new FileInputStream(entry.getFile());
}
}
return versionInputStream;
}
I get null pointer exception when i do versionInputStream = new FileInputStream(entry.getFile());
I know that we can first save this file in directory and then read the file but i dont want to save this file in directory.
Is there some way I can read this file without saving the file to some dir?
There is no file for an entry of an archive you read. TarArchiveEntry's getFile method only returns anything useful when the entry has been created with a File-arg constructor, which only makes sense when creating an archive not reading it.
The stream you are looking for is the TarArchiveInputStream itself after you've positioned it at the entry you want to read, i.e.
if (!entry.isDirectory() && entry.getName().equals("version.txt")) {
versionInputStream = debInputStream;
break;
}
note the break.
The not-yet-released (an no, no release date, yet) Commons Compress 1.21 will contain a new TarFile class that provides random-access to archives read from a seekable source (like a File) and will make your task more convenient.

when file moved/renamed - what's the difference between java RAF and File

I only want to discuss about this in java/linux context.
RandomAccessFile rand = new RandomAccessFile("test.log", "r");
VS
File file = new File("test.log");
After the creation, we start reading the file to the end.
In java.io.File case, it will throw IOException when reading the file if you mv or delete the physical file prior to the file reading.
public void readIOFile() throws IOException, InterruptedException {
File file = new File("/tmp/test.log");
System.out.print("file created"); // convert byte into char
Thread.sleep(5000);
while (true) {
char[] buffer = new char[1024];
FileReader fr = new FileReader(file);
fr.read(buffer);
System.out.println(buffer);
}
}
But in RandomFileAccess case, if you mv or delete the physical file prior to the file reading, it will finish reading the file without errors/exceptions.
public void readRAF() throws IOException, InterruptedException {
File file = new File("/tmp/test.log");
RandomAccessFile rand = new RandomAccessFile(file, "rw");
System.out.println("file created"); // convert byte into char
while (true) {
System.out.println(file.lastModified());
System.out.println(file.length());
Thread.sleep(5000);
System.out.println("finish sleeping");
int i = (int) rand.length();
rand.seek(0); // Seek to start point of file
for (int ct = 0; ct < i; ct++) {
byte b = rand.readByte(); // read byte from the file
System.out.print((char) b); // convert byte into char
}
}
}
Can anyone explain to me why ? Is there anything to do with file's inode?
Unlike RandomAccessFile or say, InputStream and many other java IO facilities, File is just an immutable handle that you drag from time to time when you need to do filesystem gateway actions. You may think of it as the reference: File instance is pointing to some specified path. On the other hand RandomAccessFile have notion of path only at construction time: it goes to the specified path, opens file and acquires file system descriptor -- you may think of it as an unique id of a given file, which do not changes on move and some other operations -- and uses this id throughout it's lifetime to address file.
The OS based file system services such as creating folders, files, verifying the permissions, changing file names etc., are provided by the java.io.File class.
The java.io.RandomAccessFile class provides random access to the records that are stored in a data file. Using this class, reading and writing , manipulations to the data can be done. One more flexibility is that it can read and write primitive data types, which helps in structured approach in handling data files.
Unlike the input and output stream classes in java.io, RandomAccessFile is used for both reading and writing files. RandomAccessFile does not inherit from InputStream or OutputStream. It implements the DataInput and DataOutput interfaces.
There is no evidence here that you have moved or renamed the file at all.
If you did thatt from outside the program, clearly it is just a timing issue.
If you rename a file before you try to open it with the old name, it will fail. Surely this is obvious?
One of the main difference is, File can not have control over write or read directly, it requires IO streams to do that. Where as RAF, we can write or read the files.

How to get the InputStream from a files list of rtf document files?

I have a list of richTextFormat documents that I need to loop through and get the InputStream from each file to merge with another document. I used this code to get the files:
List<File> rtfFilesList = new ArrayList<File>();
File[] files = new File(<path to files>).listFiles();
for (File file : files) {
if (file.isFile() && file.getName().endsWith(".rtf")) {
FilenameUtils.removeExtension(".rtf");
rtfFilesList.add(file);
}
}
That gets me the files fine, but now I want to loop through the list, as in:
for(File file : rtfFilesList){
//Get the document stream from each file here.
...
I don't know how to get the File cast to a specific type of file. API didn't seem to really support that.
Any ideas on this one?
Thanks,
James
Okay, I wasn't doing this quite right. What I really needed was:
for(File file : rtfTemplateList){
try {
fileInputStream = new FileInputStream(file);
byte[] byteArray = new byte[(int) file.length()];
fileInputStream.read(byteArray);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
etc...
What I found after writing down what I wanted to do was really get a byteArrayInputStream to pass to a third party software generator to create a merged rtf file. So using the file in a for loop was correct, but then I just needed to get the stream after that.
I hope this helps someone.

My java code is flawed, but i dont understand why

I am very new at java and my be missing something very basic. When i run my code i am trying to add value to accounts created in the code. When i try to run the code i recieve an error that a file cannot be found, but i thought that the file was created inside the code.
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
class DoPayroll
{
public static void main(String args[])
throws
IOException
{
Scanner diskScanner =
new Scanner(new File("EmployeeInfo.txt"));
for (int empNum = 1; empNum <= 3; empNum++)
{
payOneEmployee(diskScanner);
}
}
static void payOneEmployee(Scanner aScanner)
{
Employee anEmployee = new Employee();
anEmployee.setName(aScanner.nextLine());
anEmployee.setJobTitle(aScanner.nextLine());
anEmployee.cutCheck(aScanner.nextDouble());
aScanner.nextLine();
}
}
once run i recieve the following error
Exception in thread "main" java.io.FileNotFoundException: EmployeeInfo.txt (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:106)
at java.util.Scanner.<init>(Scanner.java:636)
at DoPayroll.main(jobexe.java:11)
i thought that in the above code using new Scanner(new File("EmployeeInfo.txt") would create the new file once i input a value. Please give me a simple solution and an explanation.
It will create a new file when you write to it. However to read from it, it must already exist. You might like to check it exists with
File file = new File("EmployeeInfo.txt");
if (file.exists()) {
Scanner diskScanner = new Scanner(file);
for (int empNum = 1; empNum <= 3; empNum++)
payOneEmployee(diskScanner);
}
The File object can't find the filename you've passed. You either need to pass the full path of EmployeeInfo.txt to new File(...) or make sure current working directory is the directory that contains this file.
The File constructor does not create a file. Rather, it creates the information in Java needed to access a file on disk. You'd have to actually do file IO in Java using the created File for a new file to be created.
The Scanner constructor requires an existing File. So you need a full path to the real, valid location of EmployeeInfo.txt or to create that file using File I/O first. This tutorial on I/O in Java will help.
You are mistaking instantiating an instance of class File with actually writing a temp file to Disk. Take this line
Scanner diskScanner =
new Scanner(new File("EmployeeInfo.txt"));
And replace it with this
File newFile = File.createTempFile("EmployeeInfo", ".txt");
Scanner diskScanner = new Scanner(newFile);
Edit: Peter makes a good point. I'm face palming right now.
You thought wrong :D A Scanner needs a existing file, which seems quite logical as it reads values and without a existing file its difficult to read. The documentation also states that:
Throws:
FileNotFoundException - if source is not found
So, in short: You must provide a readable, existing file to a scanner.
As the other answer explain, the file is not created just by using new File("EmployeeInfo.txt").
You can check is the file exists using
File file = new File("EmployeeInfo.txt");
if(file.exists()) {
//it exists
}
or you can create the file (if it doesn't exists yet) using
file.createNewFile();
that method returns true if the file was created and false if it already existed.

Deleting random access file in java

I've created a random access file as follows:
RandomAccessFile aFile = null;
aFile = new RandomAccessFile(NetSimView.filename, "rwd");
I want to delete the file "afile". can anyone suggest me how to do it?
You can do that:
File f = new File(NetSimView.filename);
f.delete();
Edit, regarding your comment:
The parameter NetSimView.filename seems to be a File and not a String that contains the path to the file. So simply do:
NetSimView.filename.delete();

Categories