We are dealing with the decompression libraries/utility that uses attribute to check for the presence of directories/files within the zip.
Problem is that we are not able to set archive bit for a zip while creation. When we create zip programmatically, it wash out previous attributes as well.
We will try to set archive bit with below mentioned steps but not getting desired result so far:
1. Parse each zip entry and getExtra byte[].
2. Use Int value=32 and perform bitwise 'OR' operation.
3. setExtra byte[] after 'OR' operation.
Adding some more details:
We tried following approaches but still this issue is unresolved.
Using setAttribute() method on File system but getting the attributes are getting reset while creating zip.
Files.setAttribute(file, “dos:archive”, true)
Using File.copy() which copies the file attributes associated with the file to the target file but no success. Even existing attributes are not being retained to target file.
Files.copy(path, path, StandardCopyOption.COPY_ATTRIBUTES)
Using ZipEntry.setExtra(byte[]).
found some info online that the java doesn’t have any direct method to set attributes but as per some online articles we found that the extra field is used to set the file permissions on unix and MS DOS file attributes. This is an undocumented field and we didn’t find any reliable information online. Basically, initial 2 bytes are used for unix and last 2 bytes are used for DOS file attributes. We tried setting DOS file attributes with different values in it.
ZipEntry.setExtra(byte[]) - Sets the optional extra field data for the entry.
Using winzip command line tool but not an elegant solution.
I assume it is DOS (Windows)
With Java 7
import java.nio.file.Files;
import java.nio.file.Path;
File theFile = new File("yourfile.zip");
Path file = theFile.toPath();
Files.setAttribute(file, "dos:archive", true);
see: http://kodejava.org/how-do-i-set-the-value-of-file-attributes/
Related
This question already has an answer here:
How can you get the size of a file in an archive using TrueZip?
(1 answer)
Closed 6 years ago.
I am using truezip version (7.7.9) to update a archive file.
The way I am doing it is as follows
File entry = new TFile(filepath);
writer = new TFileWriter(entry);
writer.append("MyString");
writer.flush();
long fileSize = entry.length(); // which always gives value as 0
I need the exact file size for some purpose
But this always gives 0
Is there any other way I can get that.
I read the documentation of TFile class\
https://truezip.java.net/apidocs/de/schlichtherle/truezip/file/TFile.html#length()
couldn't quite understand what it does
From the FAQ:
Every now and then you might want to treat an archive file like a
regular file rather than a virtual directory. For example, when trying
to obtain the length of the archive file in bytes. You would normally
do this by calling the method File.length(). However, if the File
object is an instance of the TFile class and the path has been
detected to name a valid archive file, then this method would always
return zero. This is because you might have changed the archive file
and then it would be impossible to return a precise result until the
changes have been committed to the target archive file.
It seems you can either compute the size of the file before changing it and then add the size of what you are appending, or you need to write the file and then call File.length(). You can do this by calling TVFS.unmount() or TVFS.unmount(TFile)
See this article at official page
The API should not detect an individual archive file as a virtual directory. How can I do this
Look at this
[...]
However, if the File object is an instance of the TFile class and the path has been detected to name a valid archive file, then this method would always return zero. This is because you might have changed the archive file and then it would be impossible to return a precise result until the changes have been committed to the target archive file..
It also applies on TPath
I wonder if you can use Files.size(path) in order to get what you need (after & before changes on your TZip)
Hope It will help.
If the archive file is valid, then it returns 0. If there is any problem occurs then it will give IOException.
If you change anything, then you need to call the method TFile.umount() to commit all changes.
Then use the following method to obtain a TFile which does not detect the archive file and call its length() method:
In TrueZIP 7.5, you can just call TFile.toNonArchiveFile()
// Note that the actual path may refer to anything, even a nested archive file.
TFile inner = new TFile("outer.zip/inner.zip");
TFile file = inner.toNonArchiveFile(); // convert - since TrueZIP 7.5
... // there may be some I/O here
TVFS.umount(inner); // unmount potential archive file
// Now you can safely do any I/O to $file.
long length = file.length();
You can do it by another way also:
private static TFile newNonArchiveFile(TFile file) {
return new TFile(file.getParentFile(), file.getName(), TArchiveDetector.NULL);
}
Resource Link:
How can you get the size of a file in an archive using TrueZip?
I am creating a web application which will allow the upload of shape files for use later on in the program. I want to be able to read an uploaded shapefile into memory and extract some information from it without doing any explicit writing to the disk. The framework I am using (play-framework) automatically writes a temporary file to the disk when a file is uploaded, but it nicely handles the creation and deletion of said file for me. This file does not have any extension, however, so the traditional means of reading a shapefile via Geotools, like this
public void readInShpAndDoStuff(File the_upload){
Map<String, Serializable> map = new HashMap<>();
map.put( "url", the_upload.toURI().toURL() );
DataStore dataStore = DataStoreFinder.getDataStore( map );
}
fails with an exception which states
NAME_OF_TMP_FILE_HERE is not one of the files types that is known to be associated with a shapefile
After looking at the source of Geotools I see that the file type is checked by looking at the file extension, and since this is a tmp file it has none. (Running file FILENAME shows that the OS recognizes this file as a shapefile).
So at long last my question is, is there a way to read in the shapefile without specifying the Url? Some function or constructor which takes a File object as the argument and doesn't rely on a path? Or is it too much trouble and I should just save a copy on the disk? The latter option is not preferable, since this will likely be operating on a VM server at some point and I don't want to deal with file system specific stuff.
Thanks in advance for any help!
I can't see how this is going to work for you, a shapefile (despite it's name) is a group of 3 (or more) files which share a basename and have extensions of .shp, .dbf, .sbx (and usually .prj, .sbn, .fix, .qix etc).
Is there someway to make play write the extensions with the tempfile name?
in my project, i have a functionality of uploading zip.
when user upload any zip, my system extract that file and display the folder structure to user.
if zip file contain the file have name like Õ.txt then it will bi Display like O.txt.
ZipFile zipFile = new ZipFile(filePath, Charset.forName("UTF8"));
Enumeration entries = zipFile.entries();
while(entries.hasMoreElements())
{
ZipEntry entry = (ZipEntry)entries.nextElement();
System.out.println(entry.getName());
}
above is my code to read zip entry.
now, when i try to get the Name of entry, it will give me O.txt instead of Õ.txt.
i have test this code with JDK 7 but having the same result.
i have also tried the different encoding type like CP437, IBM437, ISO-8859-1 and ISO-8859-1 but no change in the result.
so pleas suggest me the way which can support all the character at the time of getting entry from the zip file
Thanks & Regards
Yatin
It seems there may be something wrong with your environment and not necessarily the way you access the ZIP file. Here's a check list:
Does the ZIP file really contain a UTF-8 encoded entry with that name? Use a tool like 7-Zip to verify.
Does the JVM use the correct character set? Check the system property file.encoding.
Does the encoding of your output terminal / window match this setting?
After all, the result will only be correct if all elements of the processing chain use correct settings.
I would like to know whether or not there is some way of marking a file to identify whether or not the file contains x.
Consider the following example:
During a batch conversion process I am creating a log file which lists the success / failure of individual conversions.
So the process is as follows:
start conversion process
create log file named batch_XXX_yyyy_mm_dd.log
try to convert 'a'
write success to log file
try to convert 'b'
write success to log file
...
try to convert 'z'
write success to log file
close and persist log file
What I would like to be able to do is mark a file in some way that identifies whether any of the conversions logged in the file were unsuccessful.
I do not want to change the file name (visibly) and I do not want to open the file to check for a marker.
Does anyone have any ideas on how this could be achieved?
You can add file attributes in Java 7 through the java.nio.file.Files class.
So it would be possible to mark whether a file contains X using the Files.setAttribute() method:
Files.setAttribute( "path/to/file", "containsX", true );
And then check whether the file does contain X using the Files.getAttribute( ) method:
Files.getAttribute( "path/to/file", "containsX" )
If you are looking into say
file.log
create another file which will maintain this info say
file.log.status
Your status file can then contain all the information you need. It will be easier to get the status of conversion for all the files as well as easy to map back to original file given a status file.
In a unit test I am overwriting a config file to test handling bad property values.
I am using Apache Commons IO:
org.apache.commons.io.FileUtils.copyFile(new File(configDir, "xyz.properties.badValue"), new File(configDir, "xyz.properties"), false)
When investigating the file system I can see that xyz.properties is in fact overwritten - size is updated and the content is the same as that of xyz.properties.badValue.
When I complete the test case which goes through code that reads the file into a Properties object (using a FileReader object) I get the properties of the original xyz.properties file, not the newly copied version.
Through debugging where I single step and investigate the file I can rule out it being a timing issue of writing to the file system.
Does the copy step somehow hold a file handle? If so how would I release it again?
If not, does anybody have any idea why this happens and how to resolve it?
Thanks.
If you initialized the FileReader object before this object, then it will have already stored a temp copy of the old version.
You'll need to reset it:
FileReader f = new FileReader("the.file");
// Copy and overwrite "the.file"
f = new FileReader("the.file");
In the Unix filesystem model, the inode containing the file's contents will persist as long as someone has an open filehandle into the file, or there is a directory entry pointing to it.
Replacing the file's name in the directory, does not remove the inode (contents of the file), so your already-open filehandle can continue to be used.
This is actually exploitable to create temporary files that never need to be cleaned up: create the file, then unlink it immediately, while keeping it open. When you close the file handle, the inode is reaped
I realize that this doesn't answer your question directly, but I think that it would be better to maintain two separate files, and arrange for your code to have the name of the configuration file configurable / injected at runtime. That way, your tests can specify which config file to use, rather than overwriting a single file.