In the below code, I am trying to access a file 0.txt located in my home directory. The path to the home directory is saved within a string and the name 0.txt is appended to it upon call (0 is a reference counter which will change values as the program runs. For the sake of the question, I'll refer to it as 0).
func loadfile(counter: Int) -> String { // counter here is assumed to be "0"
var contents = String()
var defaultpath = ("~/" as NSString).stringByExpandingTildeInPath as String
do {
contents = try String(contentsOfFile: defaultpath.stringByAppendingString(String("\(counter).txt")))
return contents
} catch {
print("For some reason, the file couldn't be accessed.")
return "failed"
}
}
However, every time this block of code runs, the return value is failed and the line For some reason, the file couldn't be accessed is printed, even though ~/0.txt exists. Does anyone have an idea as to why this abnormal behavior is occurring, and if so, how should I resolve this issue??
Side question: is there a way to print the errors generated by the try-catch block to stdout?
You need to add a separator to the filename:
contents = try String(contentsOfFile: defaultpath.stringByAppendingString(String("/\(counter).txt")))
Note the forward slash at the beginning of the filename. The defaultPath does not end with a slash.
Related
I have a string which contains a path to a file:
C:\Users\user\directory\build.bat
Is there a way I can remove the word between the last backslash and the second last backslash (in this case it is directory), however I would like a way to do this several times:
First time I run the code the path should look like this:
C:\Users\user\build.bat
If I run the code on the new string I just got from running the program the first time, the output should be like this:
C:\Users\build.bat
Yes, this is very much possible. I propose the following pattern:
^(.+)\.-\(.-)$ - this will match the entire path, matching first the directories up to the parent directory and then the filename. Use it as follows:
local function strip_parent_dir(path)
local path_to_parent, filename = path:match[[^(.+)\.-\(.-)$]]
return path_to_parent .. "\\" .. filename
end
which can then be used as follows:
print(strip_parent_dir[[C:\Users\user\directory\build.bat]]) -- C:\Users\user\build.bat
print(strip_parent_dir(strip_parent_dir[[C:\Users\user\directory\build.bat]])) -- C:\Users\build.bat
another option would be to split the path by the path delimiter (backslash), inserting the parts into a table, then removing the penultimate entry, finally concatenating the parts; this is slightly longer but may be considered more readable (and it may have better asymptotic performance):
local function strip_parent_dir(path)
local parts = {}
for part in path:gmatch"[^\\]+" do
table.insert(parts, part)
end
table.remove(parts, #parts - 1)
return table.concat(parts, "\\")
end
the results are the same. Choose whatever you consider more readable.
I've a text file which I'll be using it to write content.. But every time before I write something to the file, I wish to clear the content without deleting the file..
How would I achieve the above? Any suggestions?
With text files you can simply set it to an empty string.
file.text = ''
I would use the setBytes method on java.io.File and provide it with an empty byte array:
file.bytes = new byte[0]
Passing an empty list also works, impressively.
file.bytes = []
Presumably, you want simply to overwrite the file with new content. To do that:
def content = ...
new File("test.txt").withWriter { writer ->
writer.write(content)
}
Note that File.withWriter will do all the usual housekeeping re: open/close file.
Hey what's up everyone?
I have a simple app to display the file size of files selected by users. The problem is that when the file is located within a folder that has spaces in the folder name or special characters like accents (á é ç) the file path uses different symbols and then I can't get the file size.
The folder is: /Users/home/Checking/First Box
This is my code and the output:
var path = url.absoluteString?.stringByReplacingOccurrencesOfString("file://", withString: "", options: nil, range: nil)
var filePath = path
var attr:NSDictionary? = NSFileManager.defaultManager().attributesOfItemAtPath(filePath!, error: nil)
if let _attr = attr {
fileSize = _attr.fileSize();
}
println(fileSize)
println(filePath!)
And the output is nil for the file size and /Users/home/Checking/First%20Box for the file path.
Also if I select a folder with accent on its name like /Users/home/Checking/Café the output for the path will be /Users/home/Checking/Cafe%CC%81
One solution, which is the one I am using using stringByReplacingOccurrencesOfString but this adds a lot of line to the code since there are many characters with accent throughout the languages around the world and I was wondering if there's another more simple way to do this.
Any help will be much appreciated.
The problem is that you are using a wrong (and too complicated) method
to convert a file URL to a path.
Example:
let url = NSURL(fileURLWithPath: "/ä/ö/ü")!
println(url.absoluteString!) // file:///a%CC%88/o%CC%88/u%CC%88
println(url.path!) // /ä/ö/ü
As you see, .absoluteString returns a HTML string with percent escapes,
whereas .path returns the file path. So your code should look like this:
if let filePath = url.path {
println(filePath)
if let attr : NSDictionary = NSFileManager.defaultManager().attributesOfItemAtPath(filePath, error: nil) {
let fileSize = attr.fileSize();
println(fileSize)
// ...
}
}
I have a directory with circa 3k CSV files containing various data, I need to collate these into a single file at some point, but first I need to remove all of the header rows from each file.
Usually for this I would collate the files, and then simply open in Excel, and filter to the header rows before deleting them all. Unfortunately, these sum to something around 9M rows, and Excel doesn't like that...
Can anybody think of a way around this? Preferably some sort of batch script that will run through all files in a directory.
Thanks in advance,
A.
The following assumes the first line of each file is the header line to be eliminated.
It will only work properly if none of the files contain the <TAB> character, and none of the files is too large. I can't remember the specifics, but at some point, MORE with redirected output will hang waiting for a keypress if the input file gets too large.
(for %F in (*.csv) do #more +1 "%F") >concat_csv.txt
I made sure to give the output file a different extension so that the command does not try to process the output! An alternative is to redirect the output to a CSV file but in a different folder.
If you want to use this in a batch file, then double up the percents (%F becomes %%F)
I am not sure this is what you are looking for... Here is one way to get rid of the duplicate headers in C#. The main purpose of the code is to store one header is string header and to read the files by skipping the first row (while (rdr.Peek() != -1)).
I have also used a dictionary to store the rows of each csv file. This will prevent duplicate rows in different csv files to be included (I am not sure if this function will be helpful in your case).
Imagine fname is a string array that contains the files you wish to merge.
Dictionary<string, string> dict = new Dictionary<string, string>();
string destinationFile = <write path of your destination file>;
string dir = <write path of your original directory>
string header = "";
if (dir.Length != 0)
{
foreach (string f in fnames)
{
using (StreamReader rdr = new StreamReader(dir + "\\" + f))
{
header = rdr.ReadLine();
while (rdr.Peek() != -1)
{
string ln = rdr.ReadLine();
string[] split_ln = ln.Split(',');
string value = (split_ln.Length != 2) ? string.Join(",", split_ln.Skip(1)) : split_ln[1];
dict.Add(split_ln[0], value);
}
}
}
using (StreamWriter wr = new StreamWriter(destinationFile))
{
wr.WriteLine(header);
foreach (var pair in dict)
{
wr.WriteLine("{0},{1}", Convert.ToString(pair.Key), pair.Value);
}
}
}
Can somebody explain me please why FreeImage library is not recognizing my variable as a valid filename for the method Load, I tried the following code:
var fileName = "C:\\images\\myimage.tif";
var dib = FreeImage.Load(FREE_IMAGE_FORMAT.FIF_TIFF, fileName, 0);
And it's not working, the object dib is always empty (the image is not being loaded), but when I tried the following code:
const string fileName = "C:\\images\\myimage.tif";
var dib = FreeImage.Load(FREE_IMAGE_FORMAT.FIF_TIFF, fileName, 0);
The result is successful, the problem is that I need that image path value to be a normal variable (NOT const), because I work with different images each time, and this images could be anything.
How could I solve this issue, or it's a limitation of the library?
Thanks.
The first thing I see, you are setting the first example as a var instead of string. Define your variable as a string.
I would try that, you dont need the const to make it work I don't believe.
string fileName = "C:\\images\\myimage.tif";