I am trying to modify a value of the dbVersion property for this ini file
[Settings]
Access=ReadWrite
Type=1
AutomationDbString=jdbc:mysql:ser=php&password=php
automationServerTestResultPath=/testresult/
automationServerTestResultPathWrite=testresult
automationServerTestResultPathRead=http:testresult
automationServerBuildPath=\testresult\\builds
automationServerReferenceFilesPath=\\reference_files
automationToolBaseUrl=http:/dpa
agentInstallBuildFolder = c:\\dev\\builds
agentAntLogFolder = c:\\dev\\logs
exportToTaf=true
dbEnable=true
dbVersion=606A8
dbName=archauto606
archticsLocation=//source/QA
userName=Administator
pwdName=hombre007!
archticsPatchLocation=patch\
[Root]
After executing this part of code the structure of my file has changed
Properties p = new Properties();
p.load(new FileInputStream("C:\\agent\\Testcomplete2.ini"));
System.out.println("dbVersion = " + p.getProperty("dbVersion"));
p.setProperty("dbVersion", "606A21");
p.store(new FileOutputStream("C:\\agent\\Testcomplete2.ini"), null);
#Mon Jul 22 13:49:54 EDT 2013
[Root]=
agentInstallBuildFolder=c\:\\dev\\builds
AutomationDbString=jdbc\:mysql\:ser\=php&password\=php
automationServerBuildPath=\testresult\\builds
automationServerTestResultPathWrite=testresult
dbVersion=606A21
pwdName=hombre007\!
exportToTaf=true
Type=1
userName=Administator
automationServerTestResultPathRead=http\:testresult
dbEnable=true
archticsPatchLocation=patch
[Settings]=
automationServerReferenceFilesPath=\\reference_files
Access=ReadWrite
automationToolBaseUrl=http\:/dpa
archticsLocation=//source/QA
automationServerTestResultPath=/testresult/
dbName=archauto606
agentAntLogFolder=c\:\\dev\\logs
However after executiong the line p.store , I noticed that the structure of my file has changed and i was not able to parse propelry the file . Just asking if is there a way to modify only the value without changing the structure of the file .
Thanks for helping.
It would seem that Properties.load() and Properties.store() do not necessarily guarantee the order in which entries (or even sections) are stored - possibly because the data structure used internally to store the results of load() might be a hash table or something similar. If that is the case, and your parsing breaks as a result, you'll have to either a) fix your parsing code to not rely on things being in a specific order or b) write your own code to do the replacement that doesn't rely on the load()/store() methods...
Related
Let's say, I would like to use a single object to represent a file and I'd like to get the filename (or path) of it so that I can use the name to remove the file or for other standard library procedures. I'd like to have a single abstraction which can be used with all available file-related standard library procedures.
I've found FileInfo but in my research I didn't find a get-file-name-procedure. File and FileHandle are pretty useless from a software engineering point of view because they provide no convenient abstraction and don't have members.
Is there a file abstraction (object) in Nim, which provides fast access to FileInfo as well as the file name so that a file doesn't need more than one procedure parameter?
There is no such abstraction in Nim, or any other language, simply because you are asking for an impossible thing to do with most filesystems. Consider the FileInfo structure and its linkCount field which tells you the number of hard links the file object has. But there is no way to get-a-filename from one or all of those links short of building and updating yourself a database of the whole filesystem.
While most filesystems allow access to files through paths, there is rarely a filesystem that gives paths from files because they actually don't need one! An example would be a Unix filesystem where one process opens a file through a path, then removes the path without closing the file. While the process holding the file open is alive, that file won't actually disappear, so you would have the case of a file without path.
The issue of handling paths, especially considering cross platform applications, involves its own can of worms: if you store paths as strings, what is the path separator and how do you escape it? Does your filesystem support volumes that require special case handling? What string encoding do paths use to satisfy all users? Just the encoding issue requires tons of tables and conversions which would bog down every other API wishing to get just a file like handle to read or write bytes.
A FileInfo is just a snapshot of the state of the file at a given time, a file handle is the live file object you can operate on, and a path (or many paths if your filesystem supports hard links) is just a convenience name for end users.
These are all very different things, which is why they are separate. Your app may need a more complex abstraction than other programmers are willing to tolerate, so create own abstraction which holds together all the individual pieces you need. For instance, consider the following structure:
import os
type
AppFileInfo = object
fileInfo: FileInfo
file: File
oneOfMany: string
proc changeFileExt(appFileInfo: AppFileInfo, ext: string): string =
changeFileExt(appFileInfo.oneOfMany, ext)
proc readAll(appFileInfo: AppFileInfo): string =
readAll(appFileInfo.file)
Those procs simply mimic the respective standard library APIs but use your more complex structure as inputs and transform it as needed. If you are worried about this abstraction not being optimised due to the extra proc call you could use a template instead.
If you follow this route, however, at some point you will have to ask yourself what is the lifetime of an AppFileInfo object: do you create it with a path? Do you create it from a file handle? Is it safe to access the file field in parts of your code or has it not been initialised properly? Do you return errors or throw exceptions when something goes wrong? Maybe when you start to ask yourself these questions you'll realise they are very app specific and are very difficult to generalise for every use case. Therefore such a complex object doesn't make much sense in the language standard library.
I created the missing solution myself. I basically extended the File type using a global encapsulated table. Extending Types like this could be a useful idiom in Nim because of UFCS.
import tables
type FileObject = object
file : File
mode : FileMode
path : string
proc initFileObject(name: string; mode: FileMode; bufsize = -1) : FileObject =
result.file = open(name, mode, bufsize)
result.path = name
result.mode = mode
var g_fileObjects = initTable[File, FileObject]()
template get(this: File) : var FileObject = g_fileObjects[this]
proc openFile*(filepath: string; mode: FileMode = fmRead; bufsize = -1) : File =
var fileObject = initFileObject(filepath, mode, bufsize)
result = fileObject.file
g_fileObjects[result] = fileObject
proc filePath*(this: File) : string {.raises: KeyError.} =
return this.get.path
proc fileMode*(this: File) : FileMode {.raises: KeyError.} =
return this.get.mode
from os import tryRemoveFile
proc closeOrDeleteFile[delete = false](this: File) : bool =
result = g_fileObjects.hasKey(this)
if result:
when delete:
result = this.filepath.tryRemoveFile()
g_fileObjects.del(this)
this.close()
proc closeFile*(this: File) : bool = this.closeOrDeleteFile[:false]
proc deleteFile*(this: File) : bool = this.closeOrDeleteFile[:true]
Now you can write
var f = openFile("myFile.txt", fmWrite)
var g = openFile("hello.txt", fmWrite)
echo f.filePath
echo f.deleteFile()
g.writeLine(g.filePath)
echo g.closeFile()
I need to read a text file with readLines() and I've already found this question, but the code in the answers always uses some variation of javaClass; it seems to work only inside a class, while I'm using just a simple Kotlin file with no declared classes. Writing it like this is correct syntax-wise but it looks really ugly and it always returns null, so it must be wrong:
val lines = object {}.javaClass.getResource("file.txt")?.toURI()?.toPath()?.readLines()
Of course I could just specify the raw path like this, but I wonder if there's a better way:
val lines = File("src/main/resources/file.txt").readLines()
Thanks to this answer for providing the correct way to read the file. Currently, reading files from resources without using javaClass or similar constructs doesn't seem to be possible.
// use this if you're inside a class
val lines = this::class.java.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
// use this otherwise
val lines = object {}.javaClass.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
According to other similar questions I've found, the second way might also work within a lambda but I haven't tested it. Notice the need for the ?. operator and the lines?.let {} syntax needed from this point onward, because getResourceAsStream() returns null if no resource is found with the given name.
Kotlin doesn't have its own means of getting a resource, so you have to use Java's method Class.getResource. You should not assume that the resource is a file (i.e. don't use toPath) as it could well be an entry in a jar, and not a file on the file system. To read a resource, it is easier to get the resource as an InputStream and then read lines from it:
val lines = this::class.java.getResourceAsStream("file.txt").bufferedReader().readLines()
I'm not sure if my response attempts to answer your exact question, but perhaps you could do something like this:
I'm guessing in the final use case, the file names would be dynamic - Not statically declared. In which case, if you have access to or know the path to the folder, you could do something like this:
// Create an extension function on the String class to retrieve a list of
// files available within a folder. Though I have not added a check here
// to validate this, a condition can be added to assert if the extension
// called is executed on a folder or not
fun String.getFilesInFolder(): Array<out File>? = with(File(this)) { return listFiles() }
// Call the extension function on the String folder path wherever required
fun retrieveFiles(): Array<out File>? = [PATH TO FOLDER].getFilesInFolder()
Once you have a reference to the List<out File> object, you could do something like this:
// Create an extension function to read
fun File.retrieveContent() = readLines()
// You can can further expand this use case to conditionally return
// readLines() or entire file data using a buffered reader or convert file
// content to a Data class through GSON/whatever.
// You can use Generic Constraints
// Refer this article for possibilities
// https://kotlinlang.org/docs/generics.html#generic-constraints
// Then simply call this extension function after retrieving files in the folder.
listOfFiles?.forEach { singleFile -> println(singleFile.retrieveContent()) }
In order to have the same url that work for both Jar or in local, the url (or path) needs to be a relative path from the repository root.
..meaning, the location of your file or folder from your src folder.
could be "/main/resources/your-folder/" or "/client/notes/somefile.md"
The url must be a relative path from the repository root.
it must be "src/main/resources/your-folder/" or "src/client/notes/somefile.md"
Now you get the drill, and luckily for Intellij Idea users, you can get the correct path with a right-click on the folder or file -> copy Path/Reference.. -> Path From Repository Root (this is it)
Last, paste it and do your thing.
I wonder how to convert a dm3 file into .jpg/jpeg images? there is test annotation and scale bar on the image. I setup a script but it always show that "the format cannot contain the data to be saved". This can be done via file/batch convert function. So how to realize the same function in script? Thanks
image test:=IntegerImage("test",2,1,100,100)
test.ShowImage()
image frontimage:=GetFrontImage()
string filename=getname(frontimage)
imagedisplay disp = frontImage.ImageGetImageDisplay(0)
disp.applydatabar()
ImageDocument frontDoc = GetFrontImageDocument()
string directoryname, pathname
number length
if(!SaveAsDialog("","Do Not Change Me",directoryname)) exit(0)
length=len(directoryname)-16
directoryname=mid(directoryname,0,length)
pathname=directoryname+filename
frontDoc.ImageDocumentSaveToFile( "JPG Format", pathname )
To convert to jpg you have to use "JPEG/JFIF Format" as the handler (=format).
It has to be exactly this string in the ImageDocument.ImageDocumentSaveToFile() function. Other formats are mentioned in the help (F1 > Scripting > Objects > Document Object Model > ImageDocument Object > ImageDocumentSaveToFile() function). Those are (for example):
'Gatan Format'
'Gatan 3 Format'
'GIF Format'
'BMP Format'
'JPEG/JFIF Format'
'Enhanced Metafile Format'
In your code you are using the SaveAsDialog() to get a directory. This is not necessary. You can use GetDirectoryDialog() to get a directory. This saves you the name operation for the directoryname and avoids problems when users do change your filename.
Also for concatinating paths I prefer using PathConcatenate(). On the first hand this makes your code a lot more readable since its name tells what you are doing. On the other hand this also takes care of the directory ending with \ or not and other path related things.
The following code is what I think you need:
Image test := IntegerImage("test", 2, 1, 100, 100);
test.ShowImage();
Image frontimage := GetFrontImage();
ImageDisplay disp = frontImage.ImageGetImageDisplay(0);
disp.applydatabar();
ImageDocument frontDoc = GetFrontImageDocument();
string directoryname;
if(!GetDirectoryDialog("Select directory", "C:\\\\", directoryname)){
// ↑
// You can of course use something else as the start point for selection here
exit(0);
}
string filename = GetName(frontimage);
string pathname = directoryname.PathConcatenate(filename);
frontDoc.ImageDocumentSaveToFile("JPEG/JFIF Format", pathname);
This answer is correct and should be accepted. Your problem is the wrong file-type string. You want to use "JPEG/JFIF Format"
A bit more general information on image file saving in DigitalMicrograph.
One doesn't save images but always imageDocuments that can contain one, more, or even zero image objects in them. Script-commands that save an image like SaveAsGatan() really just call things like: ImageGetOrCreateImageDocument().ImageDocumentSaveToFile()
The difference doesn't really matter for simple one-image-in-document type images, but it can make a difference when there are multiple images in a document, or when a single image is displayed multiple times simultaneously (which can be done.) So it is always good to know what "really" goes on.
ImageDocuments contain some properties relating to saving:
A save format (“Gatan Format”, “TIFF Format”, …)
Default value: What it was opened with, or last used save-format in case of creation
Script commands: ImageDocumentGetCurrentFileSaveFormat() ImageDocumentSetCurrentFileSaveFormat()
A current file path:
Default value: What it was opened from, or empty
Script commands: ImageDocumentGetCurrentFile() ImageDocumentSetCurrentFile()
A dirty-state:
Default value: clean when opened, dirty when created
Script commands: ImageDocumentIsDirty() ImageDocumentClean()
A linked-to-file state:
Default value: true when opened, false when created
Script commands: ImageDocumentIsLinkedToFile()
There are two ways of saving an imageDocument:
Saving the current document itself to disc:
void ImageDocumentSave( ImageDocument imgDoc, Number save_style ) This utilizes the current properties of the imageDocument to save it to current path in current format, marking it clean in the process. The save_style parameter determines how the program deals with missing info:
0 = never ask for path
1 = ask if not linked (or empty path)
2 = always ask
Saving a copy of the current document to disc:
void ImageDocumentSaveToFile( ImageDocument imgDoc, String handler, String fileName ) This makes a copy and save the file under provided path in the provided format. The imageDocument in memory does not change its properties. Most noticeable: It does not become clean, and it is not linked to the provided file on disc. The filename parameter specifies the saving location including the filename. If a file extension is provided, it has to match the file-format, but it can be left out. The handler parameter specified the file-format and can be anything GMS currently supports, such as:
Gatan Format
Gatan 3 Format
GIF Format
BMP Format
JPEG/JFIF Format
Enhanced Metafile Format
In short:
To save the currently opened imageDocument with a different format, you would want to do:
imageDocument doc = GetFrontImageDocument()
doc.ImageDocumentSetCurrentFileSaveFormat("TIFF Format")
doc.ImageDocumentSave(0)
While to just save a copy of the current state you would use:
imageDocument doc = GetFrontImageDocument()
string path = doc.ImageDocumentGetCurrentFile() // full path including extension!
path = PathExtractDirectory(path,0) + PathExtractBaseName(path,0) // path without file extension
doc.ImageDocumentSaveToFile("TIFF Format", path )
I want to create a copy of a database to a folder not under the data either locally or on a server I have code that looks like this:
var arcName:String = "C:\Archive\MyArchives\SomeName.nsf"
var arcDB:NotesDatabase = appDB.createCopy("", arcName);
When the action finishes (it does not generate any errors) I can't find the database anywhere. if I change the arcName to "Archives\Myarchives\SomeName,nsf" the process works correctly. But I don't want these Archives under Data.
Using the full path does not seem to make it move out from under the Data folder.
This may be a case of string escaping - in SSJS, like most C-lineage languages, \ is the escape character. Give it a shot with \\ in place of each. In my testing, it works as database.createCopy("", "C:\\Archive\\MyArchives\\SomeName.nsf").
I'm currently trying to attach image files to a model directly from a zip file (i.e. without first saving them on a disk). It seems like there should be a clearer way of converting a ZipEntry to a Tempfile or File that can be stored in memory to be passed to another method or object that knows what to do with it.
Here's my code:
def extract (file = nil)
Zip::ZipFile.open(file) { |zip_file|
zip_file.each { |image|
photo = self.photos.build
# photo.image = image # this doesn't work
# photo.image = File.open image # also doesn't work
# photo.image = File.new image.filename
photo.save
}
}
end
But the problem is that photo.image is an attachment (via paperclip) to the model, and assigning something as an attachment requires that something to be a File object. However, I cannot for the life of me figure out how to convert a ZipEntry to a File. The only way I've seen of opening or creating a File is to use a string to its path - meaning I have to extract the file to a location. Really, that just seems silly. Why can't I just extract the ZipEntry file to the output stream and convert it to a File there?
So the ultimate question: Can I extract a ZipEntry from a Zip file and turn it directly into a File object (or attach it directly as a Paperclip object)? Or am I stuck actually storing it on the hard drive before I can attach it, even though that version will be deleted in the end?
UPDATE
Thanks to blueberry fields, I think I'm a little closer to my solution. Here's the line of code that I added, and it gives me the Tempfile/File that I need:
photo.image = zip_file.get_output_stream image
However, my Photo object won't accept the file that's getting passed, since it's not an image/jpeg. In fact, checking the content_type of the file shows application/x-empty. I think this may be because getting the output stream seems to append a timestamp to the end of the file, so that it ends up looking like imagename.jpg20110203-20203-hukq0n. Edit: Also, the tempfile that it creates doesn't contain any data and is of size 0. So it's looking like this might not be the answer.
So, next question: does anyone know how to get this to give me an image/jpeg file?
UPDATE:
I've been playing around with this some more. It seems output stream is not the way to go, but rather an input stream (which is which has always kind of confused me). Using get_input_stream on the ZipEntry, I get the binary data in the file. I think now I just need to figure out how to get this into a Paperclip attachment (as a File object). I've tried pushing the ZipInputStream directly to the attachment, but of course, that doesn't work. I really find it hard to believe that no one has tried to cast an extracted ZipEntry as a File. Is there some reason that this would be considered bad programming practice? It seems to me like skipping the disk write for a temp file would be perfectly acceptable and supported in something like Zip archive management.
Anyway, the question still stands:
Is there a way of converting an Input Stream to a File object (or Tempfile)? Preferably without having to write to a disk.
Try this
Zip::ZipFile.open(params[:avatar].path) do |zipfile|
zipfile.each do |entry|
filename = entry.name
basename = File.basename(filename)
tempfile = Tempfile.new(basename)
tempfile.binmode
tempfile.write entry.get_input_stream.read
user = User.new
user.avatar = {
:tempfile => tempfile,
:filename => filename
}
user.save
end
end
Check out the get_input_stream and get_output_stream messages on ZipFile.