Writing to Networked Mapped Drive - Empty Files or Failure - windows

Sorry for reformatting my question by focusing on the real issue as follows:
I am trying to create file and write to it on a network mapped drive, which I can access, create, delete and edit files using windows explorer or CMD (Windows 10/Server 2016).
The following code should do the task:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
//The following is the file name on a network mapped drive H:
out, errc := os.OpenFile("H:/00_SC/Dest01.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if errc != nil {
fmt.Println("Error Creating/Wrting to Dest file :", errc)
}
defer out.Close()
wr := bufio.NewWriter(out)
mystring := "another line here"
d, err := wr.WriteString(mystring)
if err != nil {
fmt.Println("Error writing by Writer: ", err)
}
errflush := wr.Flush()
if errflush != nil {
fmt.Println("Error Flushing the write to file", errflush)
}
wrtd, errw := out.Write([]byte("Write something in the file"))
if errw != nil {
fmt.Println("Error of Writte call", errw)
}
fmt.Println("Length of mystring = ", len(mystring))
fmt.Println("Bytes written to buffer = ", d)
fd, errf := fmt.Fprintf(out, "Another line to the file using Fprintf %d", d)
if errf != nil {
fmt.Println("Fprintf Error: ", errf)
}
fmt.Println("Bytes written to file by Fprintf = ", fd)
fmt.Println("Bytes written to file using Write", wrtd)
}
The file was created successfully, however, neither of the methods used write to it.
Bufio.WriteString neither write nor return an error !!
Fprintf failed with unclear error message which I searched and could not find a meaning or reason.
Here the output I got when running the compiled file:
Error Flushing the write to file write H:/00_SC/Dest01.txt: The parameter is incorrect.
Error of Write call write H:/00_SC/Dest01.txt: The parameter is incorrect.
Length of mystring = 17
Bytes writen to buffer = 17
Fprintf Error: write H:/00_SC/Dest01.txt: The parameter is incorrect.
Bytes written to file by Fprintf = 0
Bytes written to file using Write 0
I would appreciate your help and guidance finding the cause of this error.
Thanks

Related

Blocking read from input file continuous streaming

I have a file open that I am constantly writing to in Golang and reading in julia live. For some reason my code fails that it read EOF at the first blocking read. What am I doing wrong?
ERROR: LoadError: EOFError: read end of file
R.buffer = open("data/live.bin", "r")
if !isopen(R.buffer)
return nothing
end
# Error is here, why would it say EOF if the file is still being written to and open?
# Read the length in first 4 bytes
msglen = read(R.buffer, UInt32)
# Then read up to that length
bytes = read(R.buffer, msglen)
Note the file is still open by golang while julia is reading.
It gets traced to an error on line 399 here https://github.com/JuliaLang/julia/blob/5584620db87603fb8be313092712a9f052b8876f/base/iostream.jl#L399
I have a feeling I need to ccall some methods to get this working.
And here is the golang code
enc, err := os.OpenFile("data/live.bin", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0660)
if err != nil {
log.Error("Error in File Create!", err.Error())
panic(err)
}
msgLen := make([]byte, 4)
for {
msg := []byte("mymessage")
binary.LittleEndian.PutUint32(msgLen, uint32(len(msg)))
_, err := enc.Write(msgLen)
if err != nil {
log.Fatal(err)
}
// Write message
_, err = enc.Write(msg)
if err != nil {
log.Fatal(err)
}
time.Sleep(5 * time.Second)
}

Fprintf Error when writing to network mapped drive

I have the following piece of code which creates an output file on a local drive and required to do the same on a network mapped drive let's call it [H:].
The file name (full path name) entered from command line as argument[1].
I am using Windows 10/Server 2016
// The following will create and append to the file when required.
sourcefile, errf := os.OpenFile(os.Args[1], s.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)
if erro != nil {
panic(erro)
}
defer outfile.Close()
I use the following function to write a map into this file.
func map2Linpro(inp map[string][]string, outfile io.Writer) {
for k, v := range inp {
_, err := fmt.Fprintf(outfile, "%s %s=%s %s\n", v[0], k, v[1], v[2])
if err != nil {
fmt.Println("Error Writing to File: ", err)
}
}
}
Everything is working just fine if the output file is on the local Drive, but when using full path with the Mapped Drive letter, I received the following error:
Error: write h://00_sc//dest01.txt: The parameter is incorrect.
I searched for any reason, but could not find one.
I would appreciate if someone help
The following is the Error I got after adding Panic(erro) after OpenFile.
Which proves that the error source is fmt.Fprintf
Error Writing to File: write H:/00_sc/dest01.txt: The parameter is incorrect.
Thanks to all.
outfile, _ := os.OpenFile(os.Args[2], os.O_CREATE|os.O_APPEND, 0666)
should read
outfile, err := os.OpenFile(os.Args[2], os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
panic(err)
}
rewrite those lines and the resulting error message should give a clue as to the cause

Out of memory when transferring large file

I'm using Go Gob to transfer large files (~ 1 GB) or many small files (~ 30 MB). Server is running in a loop, and will receive files when clients send it.
My code is working if I send one large file, or few small files, but when sending a large file for the second time, it returns a 'fatal error: runtime: out of memory'. If I send a large file, stops the program, then starts again and send another large file, it works.
It looks after receiving file via Gob and writing into a file, it is not releasing memory.
Server code
type FileGob struct {
FileName string
FileLen int
FileContent []byte
}
func handleConnection(conn net.Conn) {
transf := &FileGob{}
dec := gob.NewDecoder(conn)
err := dec.Decode(transf) // file from conn to var transf
if err != nil {
fmt.Println("error to decode into buffer:", err)
}
conn.Close()
file, err := os.Create("sent_" + transf.FileName)
if err != nil {
fmt.Println("error to create file:", err)
}
file.Write(transf.FileContent) // writes into file
fileStat, err := file.Stat()
if err != nil {
fmt.Println("error to get File Stat:", err)
}
file.Close()
fmt.Printf("File %v was transferred\n", transf.FileName)
fmt.Printf("Transferred: %d, Expected: %d\n", fileStat.Size(), transf.FileLen)
}

Why log.Println("does not log into file")?

This is my first attempt to log into files with golang.
file, _ := os.Open("logfile")
log.SetOutput(file)
log.Println("foo")
these lines build, but are not working. Why?
os.Open calls OpenFile(name, O_RDONLY, 0). This does not have the flag O_CREATE to create the file if it does not exist. Therefore you need to call OpenFile with the O_CREATE flag. I have commented out the error code:
package main
import (
"log"
"os"
"syscall"
)
const (
O_RDONLY int = syscall.O_RDONLY // open the file read-only.
O_RDWR int = syscall.O_RDWR // open the file read-write.
O_CREATE int = syscall.O_CREAT // create a new file if none exists.
O_APPEND int = syscall.O_APPEND // append data to the file when writing.
)
func main() {
/*f1, err := os.OpenFile("testlogfile1", O_RDONLY, 0) // Equivalent to os.Open("testlogfile1")
if err != nil {
log.Fatalf("error opening file1: %v", err)
}
// ** error opening file: open testlogfile1: no such file or directory exit status 1 **
defer f1.Close()
log.SetOutput(f1)
log.Println("This is a test for log 1")*/
f2, err := os.OpenFile("testlogfile2", O_RDWR | O_CREATE | O_APPEND, 0644)
/* Note that you want:
* O_RDWR to write to the file
* O_CREATE to create file if it does not exist
* O_APPEND to add additional information to existing file */
if err != nil {
log.Fatalf("error opening file2: %v", err)
}
defer f2.Close()
log.SetOutput(f2)
log.Println("This is a test for log 2")
}
Always check those errors!
Why log.Println(“does not log into file”)?
The reason is because you didn't check the file is exist or not form your code.
file, _ := os.Open("logfile")
you're using _ and didn't check the error. This is important if you wanted to write something in to file. For example look at this code :
f, err := os.OpenFile(filePath+fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
if err != nil {
// if error then you need to create the file first
err = os.MkdirAll(filePath, os.ModePerm)
}
from above code you can see the error checking using if err != nil. if the file is not exist yet then create the file first. using os.MkdirAll().
file, err := os.Open("file.go") // For read access.
if err != nil {
// do something
}
// and try to include the file path...

Golang bad file descriptor

I am getting a bad file descriptor when trying to append to a logging file within my go routine.
write ./log.log: bad file descriptor
The file exists and has 666 for permissions. At first I thought well maybe it is because each one of them is trying to open the file at the same time. I implemented a mutex to try and avoid that but got the same issue so I removed it.
logCh := make(chan string, 150)
go func() {
for {
msg, ok := <-logCh
if ok {
if f, err := os.OpenFile("./log.log", os.O_APPEND, os.ModeAppend); err != nil {
panic(err)
} else {
logTime := time.Now().Format(time.RFC3339)
if _, err := f.WriteString(logTime + " - " + msg); err != nil {
fmt.Print(err)
}
f.Close()
}
} else {
fmt.Print("Channel closed! \n")
break
}
}
}()
You need to add the O_WRONLY flag :
if f, err := os.OpenFile("./log.log", os.O_APPEND|os.O_WRONLY, os.ModeAppend); err != nil { /*[...]*/ }
To explain, here is the linux documentation for open: http://man7.org/linux/man-pages/man2/openat.2.html :
The argument flags must include one of the following access modes:
O_RDONLY, O_WRONLY, or O_RDWR. These request opening the file read-
only, write-only, or read/write, respectively.
If you check /usr/local/go/src/syscall/zerrors_linux_amd64.go:660, you can see that:
O_RDONLY = 0x0
O_RDWR = 0x2
O_WRONLY = 0x1
So by default you get a read-only file descriptor.
it used for me
the code before:
os.OpenFile(fileName, os.O_CREATE|os.O_APPEND, os.ModePerm)
and it occured the error: bad file descriptor,
then i add the os.O_WRONLY into the function
the code after:
os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm)
and it did't occured the problem.
This appears to be a discrepancy between windows and linux.
On windows os.O_APPEND implies write access, as can be seen in the code in syscall_windows.go.
if mode&O_APPEND != 0 {
access &^= GENERIC_WRITE
access |= FILE_APPEND_DATA
}
in linux the openflags are passed as-is to a linux syscall
So in DOS/WINDOWS you do not need to explicitly add a write flag with an append flag, as it is implied. (this has been default behaviour since the DOS days)
Go in linux does need the extra flag added to work.
(...but imo it should not need this flag, as appending implicitly implies that I want to write. Should I bugreport this to golang ?)

Resources