Posts: 6
Threads: 2
Joined: Oct 2021
Jan-06-2022, 03:24 AM
(This post was last modified: Jan-06-2022, 05:00 AM by Larz60+.
Edit Reason: fixed python tags
)
Need help for a file path to write to a file in a remote shared folder using with open command.
Below is my sample code:
import os
import glob
import io
# Deleting the older files from the shared folder
files = glob.glob(r"\\192.168.1.4\aaaa\*.xml")
for f in files:
print('files:',f)
os.remove(f)
file_name="testing"+".xml"
# getting Error below, not able to format the file path
with open(r"\\192.168.1.4\aaaa\" + file_name, 'w',encoding='utf-8') as wf:
wf.write("hihi test is it works?")
wf.close()
Posts: 4,754
Threads: 75
Joined: Jan 2018
sjcsvat Wrote:# getting Error below, not able to format the file path Please post the error message as well. Error messages are very useful to understand what's going on. Also you shouldn't call wf.close() . The file is automatically closed by the 'with' statement.
Posts: 2,100
Threads: 10
Joined: May 2017
files = glob.glob(r"\\192.168.1.4\aaaa\*.xml") This could not work. It's a share over network and not mounted as a real file system.
You can mount the share on Linux and work with Python on the mountpoint.
You can mount the share on Windows and work with the mounted drive.
You can also use a nice wrapper for file systems:
# python3 -m pip install fs fs.smbfs
# read the docs: https://docs.pyfilesystem.org/en/latest/index.html
import fs
with fs.open_fs("smb://USERNAME:[email protected]") as samba_share:
# samba_share is:
# BoundGlobber(pattern, path="/", namespaces=None, case_sensitive=True, exclude_dirs=None)
# https://docs.pyfilesystem.org/en/latest/globbing.html#matching-files-and-directories
samba_share.glob("**/*.xml", "/aaaa").remove()
Gribouillis likes this post
Posts: 1,582
Threads: 3
Joined: Mar 2020
(Jan-06-2022, 12:45 PM)DeaD_EyE Wrote: This could not work. It's a share over network and not mounted as a real file system.
I don't see why that should problem (on windows). Python is able to access remote shares as UNC paths through normal file operations without an explicit mount. It works fine on my windows box. I would normally do this via pathlib, but glob and the backslash r-strings don't seem to get in the way.
C:\>python
Python 3.9.0 (tags/v3.9.0:9cf6752, Oct 5 2020, 15:34:40) [MSC v.1927 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import glob
>>> files = glob.glob(r"\\10.0.0.10\USB_Storage\*")
>>> len(files)
83
>>> files[0]
'\\\\10.0.0.10\\USB_Storage\\$RECYCLE.BIN'
>>> files[3]
'\\\\10.0.0.10\\USB_Storage\\2105 Goal Tracking Meeting Dox'
Posts: 1,582
Threads: 3
Joined: Mar 2020
(Jan-06-2022, 03:24 AM)sjcsvatt Wrote: with open(r"\\192.168.1.4\aaaa\" + file_name, 'w',encoding='utf-8') as wf:
For windows paths, I prefer to use forward slashes. They work just fine. You are trying to escape them via r-strings, but there's a subtlety. Because they were developed for regex escapes, they ignore backslashes at the end. Your first string has a backslash at the end that is either ignored or ends up escaping the quote.
>>> r"\\file"
'\\\\file'
>>> r"\\file\"
File "<stdin>", line 1
r"\\file\"
^
SyntaxError: EOL while scanning string literal Better is to use use pathlib or use forward slashes. Try instead:
with open("//192.168.1.4/aaaa/" + file_name, 'w',encoding='utf-8') as wf:
Posts: 2,100
Threads: 10
Joined: May 2017
(Jan-06-2022, 05:24 PM)bowlofred Wrote: I don't see why that should problem (on windows). Python is able to access remote shares as UNC paths through normal file operations without an explicit mount. It works fine on my windows box. I would normally do this via pathlib, but glob and the backslash r-strings don't seem to get in the way.
I didn't know, that the Windows API allows accessing via samba protocol shares.
On Linux, this does not work.
Does this work?
from pathlib import Path
server = r"\\10.0.0.10"
share = "USB_Storage"
path = Path(server, share)
print(len(path.glob("*")))
Posts: 1,582
Threads: 3
Joined: Mar 2020
Jan-06-2022, 11:28 PM
(This post was last modified: Jan-06-2022, 11:28 PM by bowlofred.)
(Jan-06-2022, 10:29 PM)DeaD_EyE Wrote: Does this work?
Oddly to me, no. I am surprised. Doubled separators as the first element of a path are supposed to be protected, but it looks like Path() destroys them.
>>> Path("//10.0.0.10", "USB_Storage")
WindowsPath('/10.0.0.10/USB_Storage')
>>> Path(r"\\10.0.0.10", "USB_Storage")
WindowsPath('/10.0.0.10/USB_Storage') That seems like a bug to me (or I'm not setting something somewhere). If I can get past that limitation and construct the WindowsPath object directly, it should work okay. (And I have to turn the generator into a list to get the length)
>>> p = WindowsPath('//10.0.0.10/USB_Storage')
>>> print(len(list(p.glob("*"))))
87
Posts: 1,582
Threads: 3
Joined: Mar 2020
Ah. So Path() has to be passed a valid UNC share as the initial component (it can't assemble a UNC path from a separate server and share). So this is the functional version for me.
from pathlib import Path
unc = Path("//10.0.0.10/USB_Storage")
print(len(list(unc.glob("*")))) Output: C:\>python unc.py
87
Posts: 2,100
Threads: 10
Joined: May 2017
(Jan-06-2022, 11:28 PM)bowlofred Wrote: And I have to turn the generator into a list to get the length We need len_consume :-D
import pathlib
# this works
unc1 = pathlib.PureWindowsPath(r"\\host\share\file1")
# this seems to work also
unc2 = pathlib.PureWindowsPath(r"\\host\share") / "file1"
# the pathlib has support for unc paths, but only if the full path to the share is used
# concatenating the host part with share part will not work.
unc3 = pathlib.PureWindowsPath(r"\\host") / "share/dir/file"
print("OK", unc1)
print("OK", unc2)
print("FAIL", unc3) Output: OK \\host\share\file1
OK \\host\share\file1
FAIL \host\share\dir\file
I used PureWindowsPath because I'm on a Linux system.
For my understanding, it is important, that the str itself has the right format.
This is ok:
print(r"\\host\share\file1") Output: \\host\share\file1
This is not ok:
print("\\host\share\file1") Output: \host\share
ile1
The first \ escapes the second backslash, if a raw string literal is not used.
The \f is the control character Form Feed .
Working with backslashes in string literals without the r -prefix, will cause problems.
The second important thing for UNC paths is, that they must supply in following structure: \\host\share .
Posts: 1,582
Threads: 3
Joined: Mar 2020
In this case it was most likely the trailing backslash that was the problem (because r-strings don't unescape a trailing backslash).
|